在Jbutton的值在另一个类中更改后,使用paintComponent绘制

我有一个名为ControlsPanel的类。 如果我在此类中按JButton(Start),则boolean(isPressed)的值将更改为true。 在另一个类(CashRegistersPanel)中,我想绘制一个Image,但只有前一个类中boolean的值为true。 当然,这个布尔值在开头是假的,所以它不会绘制任何东西。

这是我的两个class级:

public ControlsPanel(final ParametersPanel panel) { start = new JButton("Start"); stop = new JButton("Stop"); start.setFont(new Font("Arial", Font.BOLD, 14)); stop.setFont(new Font("Arial", Font.BOLD, 14)); this.setLayout(null); this.setBackground(new Color(199,202,255)); this.add(start); this.add(stop); start.setBounds(10, 10, 280, 30); stop.setBounds(10, 50, 280, 30); stop.setEnabled(false); start.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { if (start.getText().equals("Start")) { start.setText("Pause"); stop.setEnabled(true); startIsPressed = true; } } }); public boolean StartisPressed() { return startIsPressed; } } 

 public class CashRegistersPanel extends JPanel{ private Image img; private int amount; private ParametersPanel parametersPanel; private ControlsPanel controlsPanel; private boolean startIsPressed; public CashRegistersPanel(ParametersPanel parametersPanel, ControlsPanel controlPanel) { this.parametersPanel = parametersPanel; this.controlsPanel = controlPanel; startIsPressed = controlsPanel.StartisPressed(); this.setBackground(new Color(237,237,237)); this.setLayout(null); CashRegister cashRegister = new CashRegister(); img = cashRegister.getImg(); amount = parametersPanel.getAmountOfRegisters(); } //Painting CashRegisters public void paintComponent(Graphics g) { if(startIsPressed) { super.paintComponent(g); for (int i = 1; i <= amount; i++) { g.drawImage(img, 30, i*50, this); } } } } 

您的问题可归结为这样:当更改发生时,如何通知另一个类中的状态更改。 这是事件驱动的GUI程序(以及其他程序类型)中的常见问题,并且是开发观察者或监听器类型设计模式的全部原因。 所以我的建议是,你以某种方式使用一个监听器设计模式。 这可以通过几种方式实现,包括:

  • 允许一个类将ActionListener附加到第一个类的JButton
  • 让观察者cla为改变状态的类添加某种类型的监听器,使用JButton的类
  • 或者我最喜欢的:完全从视图类中获取布尔值并进入模型类,并且任何想要通知的视图都要注册模型的监听器,并根据需要对模型的状态进行更改。 我经常使用后者,经常使用PropertyChangeListeners来实现这一点。

所以模型类可能看起来像:

 class Model { public static final String START = "start"; // for the property change name private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport( this); private boolean start = false; public boolean isStart() { return start; } public void setStart(boolean start) { // to set up our PropertyChangeEvent boolean oldValue = this.start; boolean newValue = start; this.start = start; // notify our listeners that the start property has changed pcSupport.firePropertyChange(START, oldValue, newValue); } // allow listeners to be added and removed public void addPropertyChangeListener(PropertyChangeListener listener) { pcSupport.addPropertyChangeListener(listener); } public void removePropertyChangeListener(PropertyChangeListener listener) { pcSupport.removePropertyChangeListener(listener); } } 

编辑例如,这是一个MV或Model-View简单示例程序:

 import java.awt.Color; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.beans.PropertyChangeListener; import javax.swing.*; import javax.swing.event.SwingPropertyChangeSupport; public class VerySimpleModelEg { private static void createAndShowGui() { Model model = new Model(); ButtonView view1 = new ButtonView(); DrawingView view2 = new DrawingView(); view1.setModel(model); view2.setModel(model); JPanel mainPanel = new JPanel(new GridLayout(1, 0)); mainPanel.add(view1); mainPanel.add(view2); JFrame frame = new JFrame("Very Simple Model Example"); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.getContentPane().add(mainPanel); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGui(); } }); } } class Model { public static final String START = "start"; // for the property change name private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport( this); private boolean start = false; public boolean isStart() { return start; } public void setStart(boolean start) { // to set up our PropertyChangeEvent boolean oldValue = this.start; boolean newValue = start; this.start = start; // notify our listeners that the start property has changed pcSupport.firePropertyChange(START, oldValue, newValue); } // allow listeners to be added and removed public void addPropertyChangeListener(PropertyChangeListener listener) { pcSupport.addPropertyChangeListener(listener); } public void removePropertyChangeListener(PropertyChangeListener listener) { pcSupport.removePropertyChangeListener(listener); } } @SuppressWarnings("serial") class ButtonView extends JPanel { public static final String PRESS_TO_START = "Press To Start"; public static final String PRESS_TO_STOP = "Press To Stop"; private Model model; private Action buttonAction = new ButtonAction(); public ButtonView() { add(new JButton(buttonAction)); setBorder(BorderFactory.createTitledBorder("Button View")); } public void setModel(Model model) { this.model = model; model.addPropertyChangeListener(new BtnViewModelListener()); } private class ButtonAction extends AbstractAction { public ButtonAction() { super(PRESS_TO_START); } @Override public void actionPerformed(ActionEvent e) { // if the button is pressed, toggle the state // of the model's start property model.setStart(!model.isStart()); } } private class BtnViewModelListener implements PropertyChangeListener { public void propertyChange(java.beans.PropertyChangeEvent evt) { // if the model's start property changes if (Model.START.equals(evt.getPropertyName())) { // change the Action's name property // which will change the JButton's text too! String text = model.isStart() ? PRESS_TO_STOP : PRESS_TO_START; buttonAction.putValue(Action.NAME, text); } }; } } @SuppressWarnings("serial") class DrawingView extends JPanel { private static final Color START_COLOR = Color.red; private static final Color STOP_COLOR = Color.blue; private Model model; public DrawingView() { setBorder(BorderFactory.createTitledBorder("Drawing View")); setBackground(STOP_COLOR); } public void setModel(Model model) { this.model = model; model.addPropertyChangeListener(new DrawingViewModelListener()); } private class DrawingViewModelListener implements PropertyChangeListener { public void propertyChange(java.beans.PropertyChangeEvent evt) { // if the model's start property changes if (Model.START.equals(evt.getPropertyName())) { // change the color of the JPanel Color bg = model.isStart() ? START_COLOR : STOP_COLOR; setBackground(bg); } }; } } 

是的,对于你非常简单的情况,这可能有点过度杀戮,但它可以很好地扩展,因为你可以将模型和GUI关注分开。