Java 使用旧实例绘制组件
我正在使用swing用java制作掷骰子程序。我有四节课: 死 鬼脸Java 使用旧实例绘制组件,java,swing,Java,Swing,我正在使用swing用java制作掷骰子程序。我有四节课: 死 鬼脸 public class DieFace { private int spotDiam,wOffset,hOffset,w,h; public int faceValue; public DieFace(){ Die die = new Die(); this.faceValue = die.getValue(); } public void draw(Graphics g, int paneWidth,
public class DieFace {
private int spotDiam,wOffset,hOffset,w,h;
public int faceValue;
public DieFace(){
Die die = new Die();
this.faceValue = die.getValue();
}
public void draw(Graphics g, int paneWidth, int paneHeight){
//draw information
}
}
模具组件
public class DieFaceComponent extends JComponent{
private static final long serialVersionUID = 1L;
DieFace face;
public DieFaceComponent(){
face = new DieFace();
System.out.println("DIEFACE" + face.faceValue);
repaint();
}
public void paintComponent(Graphics g){
revalidate();
face.draw(g,super.getWidth(),super.getHeight());
}
}
DieFaceViewer
public class DieFaceViewer{
static DieFaceComponent component;
static JFrame frame = new JFrame(); // Create a new JFrame object
public static void main(String[] args){
final int FRAME_WIDTH = 500;
final int FRAME_HEIGHT = 500;
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT); // Set initial size
frame.setTitle("Dice Simulator Version 1.0"); // Set title
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Set default close operation
component = new DieFaceComponent(); // Create a new DieFaceComponent object
frame.setLayout(new BorderLayout());
JButton btnRoll = new JButton("Roll!");
btnRoll.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
component = new DieFaceComponent();
}
});
frame.add(component, BorderLayout.CENTER); // Add DieFaceComponent object to frame
frame.add(btnRoll, BorderLayout.SOUTH);
frame.setVisible(true); // Set frame to visible
}
}
我的问题是,即使每次按下btnRoll键时都会创建一个新的Die、DieFace和DieFaceComponent对象,但用于绘制组件的值仍与初始实例相同。我做错什么了吗?提前感谢您在
ActionListener
中创建了一个新的DieFaceComponent
实例,但不使用它,它从未添加到任何内容中,因此它永远不可见。更好的解决方案将允许您触发对DieFaceComponent
的更改,这将触发对DieFace
的更改,这将触发对Die
的更改,并使整个过程只需重新绘制
本身,例如
public class Die {
private int faceValue;
public Die() {
System.out.println("Creating new Dice Object");
//setValue(roll());
roll(); // Roll sets the value any way :P
}
public int roll() {
int val = (int) (6 * Math.random() + 1);
setValue(val);
return val;
}
public int getValue() {
return faceValue;
}
public void setValue(int spots) {
faceValue = spots;
}
}
public class DieFace {
private int spotDiam, wOffset, hOffset, w, h;
//public int faceValue;
private Die die;
public DieFace() {
die = new Die();
//Die die = new Die();
// This is pointless, as you should simply as die for it's value
// when ever you need it...
//this.faceValue = die.getValue();
}
public void roll() {
die.roll();
}
public void draw(Graphics g, int paneWidth, int paneHeight) {
//draw information
}
}
public class DieFaceComponent extends JComponent {
private static final long serialVersionUID = 1L;
DieFace face;
public DieFaceComponent() {
face = new DieFace();
//System.out.println("DIEFACE" + face.faceValue);
// Pointless, as you've probably not actually been added to anything
// that could actuallyt paint you anyway...
//repaint();
}
public void roll() {
face.roll();
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//revalidate();
face.draw(g, super.getWidth(), super.getHeight());
}
}
现在,您可以在DieFace组件上调用roll
,该组件将在DieFace
上调用roll
,该组件将在Die
上调用roll
,从而更新实际值DieFaceComponent
随后将安排一次repaint
以确保其在屏幕上更新
然后你可以用它,比如
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class DiceRoller {
public static void main(String[] args) {
new DiceRoller();
}
public DiceRoller() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DiePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DiePane extends JPanel {
public DiePane() {
setLayout(new BorderLayout());
DieFaceComponent component = new DieFaceComponent();
JButton roll = new JButton("Roll");
roll.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
component.roll();
}
});
add(component);
add(roll, BorderLayout.SOUTH);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class DiceRoller {
public static void main(String[] args) {
new DiceRoller();
}
public DiceRoller() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DiePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DiePane extends JPanel {
public DiePane() {
setLayout(new BorderLayout());
Die die = new Die();
DieFaceComponent component = new DieFaceComponent(die);
JButton roll = new JButton("Roll");
roll.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
die.roll();
}
});
add(component);
add(roll, BorderLayout.SOUTH);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.dispose();
}
}
public class Die {
private PropertyChangeSupport propertyChangeSupport;
private int faceValue;
public Die() {
propertyChangeSupport = new PropertyChangeSupport(this);
System.out.println("Creating new Dice Object");
//setValue(roll());
roll(); // Roll sets the value any way :P
}
public int roll() {
int val = (int) (6 * Math.random() + 1);
setValue(val);
return val;
}
public int getValue() {
return faceValue;
}
public void setValue(int spots) {
int old = faceValue;
faceValue = spots;
propertyChangeSupport.firePropertyChange("value", old, faceValue);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener);
}
}
public class DieFace {
private int spotDiam, wOffset, hOffset, w, h;
private Die die;
public DieFace(Die die) {
this.die = die
}
public void draw(Graphics g, int paneWidth, int paneHeight) {
//draw information
}
}
public class DieFaceComponent extends JComponent {
private static final long serialVersionUID = 1L;
private DieFace face;
public DieFaceComponent(Die die) {
face = new DieFace(die);
die.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
repaint();
}
});
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//revalidate();
face.draw(g, super.getWidth(), super.getHeight());
}
}
}
现在,一个更好的解决方案是将Die
作为您的主要入口点,允许它向感兴趣的各方生成通知,并让他们自己更新
也许像
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class DiceRoller {
public static void main(String[] args) {
new DiceRoller();
}
public DiceRoller() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DiePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DiePane extends JPanel {
public DiePane() {
setLayout(new BorderLayout());
DieFaceComponent component = new DieFaceComponent();
JButton roll = new JButton("Roll");
roll.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
component.roll();
}
});
add(component);
add(roll, BorderLayout.SOUTH);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class DiceRoller {
public static void main(String[] args) {
new DiceRoller();
}
public DiceRoller() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DiePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DiePane extends JPanel {
public DiePane() {
setLayout(new BorderLayout());
Die die = new Die();
DieFaceComponent component = new DieFaceComponent(die);
JButton roll = new JButton("Roll");
roll.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
die.roll();
}
});
add(component);
add(roll, BorderLayout.SOUTH);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.dispose();
}
}
public class Die {
private PropertyChangeSupport propertyChangeSupport;
private int faceValue;
public Die() {
propertyChangeSupport = new PropertyChangeSupport(this);
System.out.println("Creating new Dice Object");
//setValue(roll());
roll(); // Roll sets the value any way :P
}
public int roll() {
int val = (int) (6 * Math.random() + 1);
setValue(val);
return val;
}
public int getValue() {
return faceValue;
}
public void setValue(int spots) {
int old = faceValue;
faceValue = spots;
propertyChangeSupport.firePropertyChange("value", old, faceValue);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener);
}
}
public class DieFace {
private int spotDiam, wOffset, hOffset, w, h;
private Die die;
public DieFace(Die die) {
this.die = die
}
public void draw(Graphics g, int paneWidth, int paneHeight) {
//draw information
}
}
public class DieFaceComponent extends JComponent {
private static final long serialVersionUID = 1L;
private DieFace face;
public DieFaceComponent(Die die) {
face = new DieFace(die);
die.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
repaint();
}
});
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//revalidate();
face.draw(g, super.getWidth(), super.getHeight());
}
}
}
这是一个简单的例子,其中,Die
是信息的产生器,其他人都想知道信息何时发生变化。它也是模型-视图-控制器范例的一种变体在paintComponent
方法中不要调用revalidate
,此外,您还应该调用super.paintComponent
,然后在ActionListener
中创建DieFaceComponent
的新实例,但不使用它,它从未添加到任何内容中,因此永远不可见。一个更好的解决方案将允许您触发对DieFaceComponent
的更改,这将触发对DieFace
的更改,这将触发对Die
的更改,并让整个过程只需repaint
本身,感谢您的精彩帖子,这是作业的一部分,因此不幸的是,我必须坚持我被允许的类:/I我实现了您的第一个解决方案,但当我调用component.roll()时;,骰子的面值不会改变至少你可以建议一个更好的设计我会的,最大的问题是必须坚持过时的swing实现