在Java类之间传递数据

时间:2014-11-20 13:38:59

标签: java colors paint

从下拉列表中选择颜色后,从GUI发送索引后,我无法从Color类中检索变量。我可以发送索引并从HashMap中检索它,我知道这是因为我使用System.out.println来检查。基本上我的问题是,我哪里出错了?我需要记住什么才能确保我再没有遇到这个麻烦?编辑:忘了提一下,发送索引的按钮是一个单独的JPanel,用于UI组件(按钮和组合框)。

//edit
class UIPanel extends JPanel{
   public MainPanel gpanel;
    public Integer data;
    public Color colval;
    public Colour col;
public UIPanel(MainPanel panel) {

        col = new Colour();

        gpanel = panel;


        Box btnBox = Box.createHorizontalBox();

        btnBox.add(setBtn = new JButton());
        btnBox.add(Box.createHorizontalGlue());
         JButton setBtn = new JButton("Set");

        final DefaultComboBoxModel colour = new DefaultComboBoxModel();
        colour.addElement("Red");
        final JComboBox colours = new JComboBox(colour);
        JScrollPane colourScroll = new JScrollPane(colours);

        btnBox.setSize(300, 100);
        btnBox.add(Box.createHorizontalGlue());

        add(btnBox, BorderLayout.NORTH);
//end of edit

Button to send Index from GUI class to Colour class    

    setBtn.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent e) {

                data= colours.getSelectedIndex();

                col.setCol(data);    
            }
        });

Color Class,其中hashmap带有颜色列表。

public class Colour{

    public Color colVal;

    HashMap<Integer, Color> map = new HashMap<Integer, Color>();

    public Colour() {
        map.put(0, Color.RED);
        map.put(1, Color.BLUE);
        map.put(2, Color.YELLOW);
        map.put(3, Color.GREEN);
    }

    public Color setCol(Integer data) {
       //Color colours;
        colVal = map.get(data);
        System.out.println("colour" + colVal);
        return colVal;
    }

    public Color getColVal() {
        return colVal;
    }

GUI类上的绘制区域,颜色将从颜色类

发送到该区域
class MainPanel extends JPanel{    
    //private Colour col;
    int px, py;
    //radius
    public Color colvals;

    public Colour col;

    public MainPanel() {  
        col = new Colour();

        this.addMouseMotionListener(new MouseMotionAdapter() {
            // store drag coordinates and repaint
                public void mouseDragged( MouseEvent event )
                {
                        px = event.getX();
                        py = event.getY();
                        repaint();
                }
                }); // end call to addMouseMotionListener
    }

    public void paint( Graphics g ) {   
        g.setColor(col.colVal);//This is where the colour value will be placed
        System.out.println(col.colVal);
        g.fillOval( px, py, 15, 15 );
    }
}

我可能错过了一些愚蠢的东西,但我似乎无法弄明白。

P.S:制作Vignere密码应用程序有多复杂?

3 个答案:

答案 0 :(得分:2)

JComboBox可以用来直接使用任何对象作为只需要考虑一件小事的项目:它将使用toString来显示标签。 (见JComboBox javadoc - Providing a Custom Renderer)。

但是我不再使用自定义渲染器,而是总是喜欢编写一个非常简单的辅助类 - 让我们称之为ComboBoxItem - 这对于任何类型的数据都是可重用的。

public class ComboBoxItem<T>
{
    private T value;
    private String label;

    public ComboBoxItem(T value, String label)
    {
        this.value = value;
        this.label = label;
    }

    public T getValue()
    {
        return this.value;
    }

    public String getLabel()
    {
        return this.label;
    }

    // important! since this is the workaround ;-)
    public String toString()
    {
        return this.label; // or whatever you like
    }
}

然后使用JComboBox代替ComboBoxItem s填充String

在您的代码中而不是

final DefaultComboBoxModel colour = new DefaultComboBoxModel();
colour.addElement("Red");
colour.addElement("Blue");
colour.addElement("Yellow");
colour.addElement("Green");
colours = new JComboBox(colourValues);

...你将使用

final DefaultComboBoxModel colour = new DefaultComboBoxModel();
colour.addElement(new ComboBoxItem<Color>(Color.RED, "Red"));
colour.addElement(new ComboBoxItem<Color>(Color.BLUE, "Blue"));
colour.addElement(new ComboBoxItem<Color>(Color.YELLOW, "Yellow"));
colour.addElement(new ComboBoxItem<Color>(Color.GREEN, "Green"));
colours = new JComboBox(colourValues);

这将使select包含ComboBoxItem s作为值,您可以通过执行以下操作来轻松访问:

// instead of getSelectedIndex()
ComboBoxItem<Color> item = (ComboBoxItem) colours.getSelectedItem(); 
Color c = item.getValue();

然后可以对任何其他类型的值重复使用相同的过程 - 即使是复杂的值。

注意:如果您的数据对象具有适当的toString()表示,您当然可以简单地将其用作select的值。

注2:如果字符串表示不够(例如,您想要显示颜色以及名称),请查看能够显示项目的ListCellRenderer任何所需的方式(通过返回任意JComponent)。

答案 1 :(得分:1)

Color类中的setCol(...)方法应为getCol(...),因为它可以充当吸气剂:

public class Colour{

    public Color colVal;

    HashMap<Integer, Color> map = new HashMap<Integer, Color>();

    public Colour() {
        map.put(0, Color.RED);
        map.put(1, Color.BLUE);
        map.put(2, Color.YELLOW);
        map.put(3, Color.GREEN);
    }

    // **** change name ****
    public Color getCol(Integer data) {
       //Color colours;
        colVal = map.get(data);
        System.out.println("colour" + colVal);
        return colVal;
    }

    // **** not sure you need this method
    public Color getColVal() {
        return colVal;
    }

并在ActionListener中检索颜色但从不对其执行任何操作。它应该是:

    public void actionPerformed(ActionEvent e) {
        data = colours.getSelectedIndex();
        Color color = col.getCol(data); // note name change

        // use Color variable, color, somehow here
        mainPanel.setColVals(color);  // something like this perhaps
        mainPanel.repaint();  // to tell the JVM to repaint the JPanel
    }

另请注意,在您的JPanel类覆盖中,您应该覆盖paintComponent方法,而不是paint方法,并且不要忘记调用超级方法。

即,

public void setColVals(Color colVals) {
   this.colVals = colVals;
}

@Override
protected void paintComponent(Graphics g)  {   

    super.paintComponent(g);

    g.setColor(colVal);
    // System.out.println(colVal);
    g.fillOval( px, py, 15, 15 );
}

修改更好的答案:

  • 彻底摆脱色彩。
  • 使用枚举将Color与String匹配,并从该枚举中创建一个JComboBox模型。
  • 使用枚举可以防止您使用魔术数字,但可能存在使用错误号码的风险,这个数字与颜色不匹配。
  • 此外,通过使用枚举,更改代码并添加更多颜色是微不足道的。只需在枚举中添加一个新项目,程序的其余部分将适应更改。
  • 将一个PropertyChangeListener从MainPanel添加到UIPanel并监听对其&#34;绑定&#34;的更改。颜色属性。
  • 将RenderingHints与Graphics2D对象一起使用,以平滑圆绘图中的锯齿。

import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;

public class ColorListenerPanel extends JPanel {
   public ColorListenerPanel() {
      UIPanel uiPanel = new UIPanel();
      MainPanel mainPanel = new MainPanel(uiPanel);

      setLayout(new BorderLayout());
      add(mainPanel, BorderLayout.CENTER);
      add(uiPanel, BorderLayout.PAGE_START);
   }

   private static void createAndShowGui() {
      ColorListenerPanel mainPanel = new ColorListenerPanel();

      JFrame frame = new JFrame("ColorListenerPanel");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class MainPanel extends JPanel {
   private static final int PREF_W = 800;
   private static final int PREF_H = 650;
   private static final int OVAL_WIDTH = 16;
   private int px, py;
   private Color color = MyColors.values()[0].getColor();

   public MainPanel(UIPanel uiPanel) {

      this.addMouseMotionListener(new MouseMotionAdapter() {
         // store drag coordinates and repaint
         public void mouseDragged(MouseEvent event) {
            px = event.getX();
            py = event.getY();
            repaint();
         }
      });

      uiPanel.addPropertyChangeListener(UIPanel.COLOR, new UiListener());
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      g.setColor(color);
      g.fillOval(px - OVAL_WIDTH / 2, py - OVAL_WIDTH / 2, OVAL_WIDTH, OVAL_WIDTH);
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private class UiListener implements PropertyChangeListener {
      @Override
      public void propertyChange(PropertyChangeEvent pcEvt) {
         // not really needed since our listener is added using
         // this property name
         if (!UIPanel.COLOR.equals(pcEvt.getPropertyName())) {
            return;
         }

         color = (Color) pcEvt.getNewValue();
         repaint();
      }
   }
}



enum MyColors {
   RED("Red", Color.RED), 
   BLUE("Blue", Color.BLUE), 
   YELLOW("Yellow", Color.YELLOW), 
   GREEN("Green", Color.GREEN);

   private String name;
   private Color color;

   private MyColors(String name, Color color) {
      this.name = name;
      this.color = color;
   }

   public String getName() {
      return name;
   }

   public Color getColor() {
      return color;
   }

   @Override
   public String toString() {
      return name;
   }

}

class UIPanel extends JPanel {
   public static final String COLOR = "color";
   private MainPanel gpanel;
   private Integer data;
   private Color color;
   private DefaultComboBoxModel<MyColors> comboModel = new DefaultComboBoxModel<>();
   private JComboBox<MyColors> colorsCombo = new JComboBox<>(comboModel);
   SetColorAction setColorAction = new SetColorAction("Set", KeyEvent.VK_S);

   public UIPanel() {
      setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
      add(colorsCombo);
      add(Box.createHorizontalStrut(5));
      add(new JButton(setColorAction));
      colorsCombo.addActionListener(setColorAction);
      add(Box.createHorizontalGlue());

      for (MyColors myColor : MyColors.values()) {
         comboModel.addElement(myColor);
      }
   }

   public void setColor(Color color) {
      Color oldValue = this.color;
      Color newValue = color;
      this.color = color;
      firePropertyChange(COLOR, oldValue, newValue);
   }

   private class SetColorAction extends AbstractAction {

      public SetColorAction(String name, int mnemonic) {
         super(name);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent evt) {
         MyColors selection = (MyColors) colorsCombo.getSelectedItem();
         if (selection != null) {
            setColor(selection.getColor());            
         }
      }
   }
}

答案 2 :(得分:0)

在此功能

 public void paint( Graphics g ) {   
    g.setColor(col.colVal);//This is where the colour value will be placed
    System.out.println(col.colVal);
    g.fillOval( px, py, 15, 15 );
}

您正在使用g.setColor(col.colVal); col.colVal将为您指定的默认值为null,您应该使用col.getColVal(),因为这是您为colVal属性创建的getter方法。

并且在setter声明public Color setCol(Integer data)中,您使用的返回类型是Color,但是当您在GUI类中使用此函数时,没有可以接受setter返回的Value的Color变量。 我不明白需要从Setter方法返回值。