从下拉列表中选择颜色后,从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密码应用程序有多复杂?
答案 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 );
}
修改更好的答案:
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方法返回值。