I have created a simulation that performs a number of calculations and then stores a point consisting of an x and y coordinate into a Point Array List.
Then I have a for loop that iterates through each point and draws that point onto the GUI. Here is my for loop that executes at the end of the simulation and the drawPoint method:
//Iterates through each point in Point Array List
for(Point i: PointArray)
{
drawPoint(g, i, black); //Draw Point
}
//Draws point onto panel
public void drawPoint(Graphics g, Point PointArray, Color color)
{
Graphics2D g2d = (Graphics2D)g;
g2d.setStroke(new BasicStroke(2f));
g.setColor(color); //g2d.setColor(Color.black);
g2d.drawOval((int)PointArray.a, (int)PointArray.b, 2, 2);
}
I want to implement a JComboBox so that the user can specify what color they want the plot to be colored when drawn. I have created 开发者_运维技巧different color objects to be used for this.
In my actionPerformed method, I also have code that handles the JButton events that start, stop and erase the simulation. This is what I have for my actionPerformed method:
public void actionPerformed(ActionEvent e)
{
Object source = e.getSource();
JComboBox cb = (JComboBox)e.getSource();
String colorName = (String)cb.getSelectedItem();
//Get Graphics on Drawing Panel
Graphics g = dPanel.getGraphics();
//if JButton source == start, do something
//if JButton source == stop, do something
//If JButton source == erase, do something
if(colorName == "Default")
{
g.setColor(black);
}
if(colorName == "Red")
{
g.setColor(startColor);
}
if(colorName == "Green")
{
g.setColor(forestGreen);
}
}
I am getting the following error: Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.JButton cannot be cast to javax.swing.JComboBox at SimulationGUI.actionPerformed(SimulationGUI.java:332)
So my question is, is what I want to do even possible, and if it is (being that my implementation does not work), what would be a way to accomplish this?
EDIT:
Here is my new action listener for the JComboBox:
colorBox.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
JComboBox cb = (JComboBox)e.getSource();
String colorName = (String)cb.getSelectedItem();
Graphics g = dPanel.getGraphics();
if(colorName.equals("Default"))
{
g.setColor(black);
}
if(colorName.equals("Red"))
{
g.setColor(startColor);
}
if(colorName.equals("Green"))
{
g.setColor(forestGreen);
}
if(colorName.equals("Blue"))
{
g.setColor(eraseColor);
}
}
});
}
Use separate ActionListeners for the ComboBox and your buttons. Right now your main problem is you are casting here expecting a JComboBox:
JComboBox cb = (JComboBox)e.getSource();
But this will fail when the button is clicked because a JButton
is not a JComboBox
. Doing this cast would be fine if it was in an ActionListener only dealing with JComboBoxes.
1) Don't use the getGraphics()
method to do painting. It may appear to work, but try minimizing and then restoring the frame and the painting will disappear. Check out Custom Painting Approaches for ideas on how to do this.
2) Don't use "==" to compare String values. Use:
colorName.equals("Red");
Actually a better solution is to store a custom `ColorItem' object in the combo box. This item would store both the String display text and the Color object. Then there is no need for multiple if statements in the ActionListener. Here is a simple example that uses this approach:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.plaf.basic.*;
public class ComboBoxItem extends JFrame implements ActionListener
{
public ComboBoxItem()
{
Vector model = new Vector();
model.addElement( new Item(1, "car" ) );
model.addElement( new Item(2, "plane" ) );
model.addElement( new Item(4, "boat" ) );
model.addElement( new Item(3, "train" ) );
model.addElement( new Item(5, "boat" ) );
JComboBox comboBox;
// Easiest approach is to just override toString() method
// of the Item class
comboBox = new JComboBox( model );
comboBox.setSelectedIndex(-1);
comboBox.addActionListener( this );
// comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
getContentPane().add(comboBox, BorderLayout.NORTH );
// Most flexible approach is to create a custom render
// to diplay the Item data
// Note this approach will break keyboard navigation if you don't
// implement a default toString() method.
comboBox = new JComboBox( model );
comboBox.setSelectedIndex(-1);
comboBox.setRenderer( new ItemRenderer() );
comboBox.addActionListener( this );
getContentPane().add(comboBox, BorderLayout.SOUTH );
}
public void actionPerformed(ActionEvent e)
{
JComboBox comboBox = (JComboBox)e.getSource();
Item item = (Item)comboBox.getSelectedItem();
System.out.println( item.getId() + " : " + item.getDescription() );
}
class ItemRenderer extends BasicComboBoxRenderer
{
public Component getListCellRendererComponent(
JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus)
{
super.getListCellRendererComponent(list, value, index,
isSelected, cellHasFocus);
if (value != null)
{
Item item = (Item)value;
setText( item.getDescription().toUpperCase() );
}
/*
if (index == -1)
{
Item item = (Item)value;
setText( "" + item.getId() );
}
*/
return this;
}
}
class Item
{
private int id;
private String description;
public Item(int id, String description)
{
this.id = id;
this.description = description;
}
public int getId()
{
return id;
}
public String getDescription()
{
return description;
}
public String toString()
{
return description;
}
}
public static void main(String[] args)
{
JFrame frame = new ComboBoxItem();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setVisible( true );
}
}
精彩评论