在Jbutton的值在另一个类中更改后,使用paintComponent绘制 [英] Drawing with paintComponent after value of Jbutton changed in another class

查看:119
本文介绍了在Jbutton的值在另一个类中更改后,使用paintComponent绘制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a class named ControlsPanel. If I press a JButton (Start) in this class, the value of a boolean (isPressed) changes to true. In another class (CashRegistersPanel) I want to draw an Image, but only of the value of the boolean in the previous class is true. Of course the value of this boolean is false in the begining, so it doesn't draw anything.

这些是我的两个类:

    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程序(以及其他程序类型)中的常见问题,并且是开发观察者或监听器类型设计模式的全部原因。所以我的建议是,你以某种方式使用一个监听器设计模式。这可以通过以下几种方式实现:

Your issue can be boiled down to simply this: how can one class be notified of a change of state in another class, when the change occurs. This is a common problem in event-driven GUI programs (and other program types as well) and is the whole reason that the observer or listener type design patterns were developed. So my suggestion is just that, that you somehow use a listener design pattern. This can be achieved in several ways including:


  • 允许一个类将ActionListener附加到第一个类的JButton

  • 让观察者cla向更改状态的类添加某种类型的侦听器,使用JButton的类

  • 或者我最喜欢的:从视图类中获取布尔值完全进入模型类,并且有任何想要被通知的视图,以便向模型注册一个监听器,并根据需要对模型状态的变化作出反应。我经常使用后者,经常使用PropertyChangeListeners来实现这一点。

所以模型类可能类似于:

So a model class could look something like:

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或模型 - 视图简单示例程序:


Edit For example, here is a M-V or Model-View simple example program:

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关注分开。

And yes, this may be a bit of over-kill for your very simple situation, but it scales up nicely since you can with this separate the model and the GUI concerns.

这篇关于在Jbutton的值在另一个类中更改后,使用paintComponent绘制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆