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

时间:2014-08-21 00:12:47

标签: java swing paintcomponent

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

这是我的两个班级:

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

1 个答案:

答案 0 :(得分:2)

您的问题可以简单地解释为:当更改发生时,如何通知另一个类中的状态更改。这是事件驱动的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);
   }
}

修改 例如,这是一个M-V或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问题区分开来。