[英]Passing Data between Java Classes
I'm having trouble retrieving the variable from my Colour class after i send the index from the GUI after selecting a colour from the drop down list. 从下拉列表中选择颜色后,从GUI发送索引后,我无法从Color类中检索变量。 I can send the index fine and retrieve it from the HashMap, i know this because i use System.out.println to check.
我可以发送索引并从HashMap中检索它,我知道这是因为我使用System.out.println来检查。 Basically my questions are, where have i gone wrong?
基本上我的问题是,我哪里出错了? and What do i need to remember to make sure i don't have this trouble again?
我需要记住什么才能确保我再没有遇到这个麻烦? Edit: forgot to mention, the button sending the index is in a seperate JPanel which is used for the UI components(buttons and combo boxes).
编辑:忘了提一下,发送索引的按钮是一个单独的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);
}
});
Colour Class where hashmap with the list of colours in. 颜色类,其中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;
}
And the paint area on the GUI class where the colour will be sent to from the colour class 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 );
}
}
I'm Probably missing something stupid out but I cant seem to figure it out. 我可能错过了一些愚蠢的东西,但我似乎无法弄明白。
PS: How complicated will it be to make a Vignere Cipher Application? PS:制作Vignere密码应用程序有多复杂?
JComboBox
can be used to directly use any Objects as items with only one little thing to consider: It will use the toString
for the label to display. JComboBox
可以直接使用任何对象作为项目,只需要考虑一件小事:它将使用toString
来显示标签。 (see JComboBox javadoc - Providing a Custom Renderer ). (请参阅JComboBox javadoc - 提供自定义渲染器 )。
But instead of using a custom renderer I always preferred to write a very simple helper class once - let's call it ComboBoxItem
- that is reusable for any kind of data. 但是我不再使用自定义渲染器,而是总是喜欢编写一个非常简单的辅助类 - 让我们称之为
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
}
}
And then populate the JComboBox
with ComboBoxItem
s instead of String
values: 然后使用
ComboBoxItem
而不是String
值填充JComboBox
:
In your code instead of 在你的代码而不是
final DefaultComboBoxModel colour = new DefaultComboBoxModel();
colour.addElement("Red");
colour.addElement("Blue");
colour.addElement("Yellow");
colour.addElement("Green");
colours = new JComboBox(colourValues);
... you will use ......你会用的
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);
This will make the select contain ComboBoxItem
s as values which you can simply access by doing the following: 这将使select包含
ComboBoxItem
作为值,您可以通过执行以下操作来访问它们:
// instead of getSelectedIndex()
ComboBoxItem<Color> item = (ComboBoxItem) colours.getSelectedItem();
Color c = item.getValue();
The same procedure can then be reused for any other kind of values - even complex ones. 然后可以将相同的过程重用于任何其他类型的值 - 甚至是复杂的值。
Note: If you have a data object with an appropriate toString() representation anyway, you can of course simply use it as a value for the select. 注意:如果您的数据对象具有适当的toString()表示,您当然可以简单地将其用作select的值。
Note2: If a string representation is not enough (eg you want to display the color along with the name), have a look at ListCellRenderer which is able to display the item in any desired way (by returning an arbitrary JComponent). 注意2:如果字符串表示不够(例如,您想要显示颜色和名称),请查看ListCellRenderer ,它能够以任何所需的方式显示项目(通过返回任意JComponent)。
Your setCol(...)
method inside of the Colour class should be getCol(...)
since it's functioning as a getter: Color类中的
setCol(...)
方法应该是getCol(...)
因为它起到了getter的作用:
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;
}
and in your ActionListener, you retrieve the color but never do anything with it. 在ActionListener中,您可以检索颜色但从不对其执行任何操作。 It should be:
它应该是:
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
}
Also note that in your JPanel class override you should override the paintComponent
method, not the paint
method, and don't forget to call the super's method. 另请注意,在JPanel类覆盖中,您应该覆盖
paintComponent
方法,而不是paint
方法,并且不要忘记调用super的方法。
ie, 即
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 );
}
Edit a better answer: 编辑更好的答案:
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());
}
}
}
}
In this Function 在这个功能
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 );
}
You are using g.setColor(col.colVal);
您正在使用
g.setColor(col.colVal);
col.colVal
will give you the default value assigned to it probably null ,You should use col.getColVal() as this is the getter method you have created for the colVal attribute. col.colVal
将为您指定的默认值可能为null,您应该使用col.getColVal(),因为这是您为colVal属性创建的getter方法。
And also in the setter declaration public Color setCol(Integer data)
the return type you are using is Color but when you are using this function in your GUI class without a Color variable which can accept a Value returned by your setter . 并且在setter声明中,
public Color setCol(Integer data)
你正在使用的返回类型是Color,但是当你在GUI类中使用这个函数而没有可以接受setter返回的Value的Color变量时。 I don't understand the need of returning values from a Setter method. 我不明白需要从Setter方法返回值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.