gpt4 book ai didi

java - 使用旧实例的paintComponent

转载 作者:行者123 更新时间:2023-12-02 04:13:47 28 4
gpt4 key购买 nike

我正在使用 swing 在 java 中制作一个掷骰子程序。我有 4 节课:

public class Die{
private int faceValue;

public Die(){
System.out.println("Creating new Dice Object");
setValue(roll());
}

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;

public DieFace(){
Die die = new Die();
this.faceValue = die.getValue();
}

public void draw(Graphics g, int paneWidth, int paneHeight){
//draw information
}
}

DieFace组件

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());

}
}

现在,您可以在 DieFaceComponent 上调用 roll,这将在 DieFace 上调用 roll,后者将调用 roll on Die,这将更新实际值。然后,DieFaceComponent 将安排一次重绘,以确保它在屏幕上更新。

然后你可以使用它,比如......

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);
}

}

}

现在,更好的解决方案是将 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 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());

}
}

}

这是 Observer Pattern 的一个简单示例,其中Die是信息的生成器,其他每个人都有兴趣知道它何时发生变化。它也是模型- View - Controller 范式的变体

关于java - 使用旧实例的paintComponent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33534632/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com