Java ActionListener issues - java

I created a frame. within the frame there is a combobox.
I am trying that each option from the combobox will create something else (JCheckBox,JRadioButton).
comboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
String selection = comboBox.getSelectedItem().toString();
label3.setText(input[comboBox.getSelectedIndex()]);
//panel_mid.removeAll();
if(comboBox.getSelectedItem().toString().equals("Pilot")){
panel_mid.removeAll();
panel_mid.add(label3,BorderLayout.WEST);
panel_mid.add(text_bottom);
panel_mid.setBorder(new TitledBorder(comboBox.getSelectedItem().toString() + " options"));
panel_mid.add(jchkCaptain);
}
if(comboBox.getSelectedItem().toString().equals("Host")){
panel_mid.removeAll();
panel_mid.add(label3,BorderLayout.WEST);
panel_mid.add(text_bottom);
panel_mid.setBorder(new TitledBorder(comboBox.getSelectedItem().toString() + " options"));
panel_mid.add(regular = new JRadioButton("Regular"));
panel_mid.add(bachir = new JRadioButton("Bachir"));
panel_mid.add(calcelan = new JRadioButton("Calcelan"));
}
if(comboBox.getSelectedItem().toString().equals("Office")){
panel_mid.removeAll();
panel_mid.add(label3,BorderLayout.WEST);
panel_mid.add(text_bottom);
panel_mid.setBorder(new TitledBorder(comboBox.getSelectedItem().toString() + " options"));
}
}
});
when picked Pilot only JCheckBox shuold appear.
when picked Host only JRadioButton shuold appear.
when picked Office nothing shuold appear.
the problem is when i pick host and then pilot and then host it doesnt show the JRadioButton.
thanks for help.

you have to tell the LayoutManager something is/are changed, LayoutManager haven't any notifier about, you have to notify programatically about this changes
use container.revalidate() and container.repaint(variable for JPanels in your case) as last code line, only one time ,after all changes to the already visible Swing GUI are done
use CardLayout for to switch between views (JPanels in your case)

Related

Java JComboBox repaint error

So I am working with JComboBox in my new program, but for some reason every time something is selected it repaints. I do not want it to repaint the entire program when something is selected, just the boxes specified. See the code below.
The first section here is from the class that contains the panel.
First here are the declarations for the JComboBox's and the Labels they edit once selected:
private JComboBox crewview = new JComboBox(SpaceGame.stuffselector);
private JComboBox resourceview = new JComboBox(SpaceGame.stuffselector1);
private JLabel crewmember, crewmember1, crewmember2;
private JLabel resourcev, resourcev1, resourcev2;
where stuff selector is an array of number digits 1 to 10
My paint method containts these, as it does not work unless I have these here:
resourceview.setLocation(400,80);
resourcev.setLocation(455,85);
resourcev1.setLocation(455,95);
resourcev2.setLocation(455,105);
crewview.setLocation(400, 20);
crewmember.setLocation(455,25);
crewmember1.setLocation(455,35);
crewmember2.setLocation(455,45);
And here are my action listeners:
private class crewviewListener implements ActionListener{
public void actionPerformed(ActionEvent e){
lifeForm temp = SpaceGame.playership.getCrewat(crewview.getSelectedIndex());
crewmember.setText("Name: " + temp.getName()); //set the text to the crew member
crewmember1.setText("Race: " + temp.getRace());
crewmember2.setText("Worth: " + temp.getWorth());
}
}
private class resourceviewListener implements ActionListener{
public void actionPerformed(ActionEvent e1){
Resource temp1 = SpaceGame.playership.getResourceat(resourceview.getSelectedIndex());
resourcev.setText("Name: " + temp1.getName()); //set the text to the crew member
resourcev1.setText("Worth: " + temp1.getWorth());
resourcev2.setText("Amount: " + temp1.getAmount());
}
}
So as you may tell be reading the code, I am trying to get it to only update the JLables when stuff in the box is selected, and not repaint everything.
JLabels are non-opaque by default. This means that whenever you change the text in the label, the background of the label must also be repainted. Therefore the panel that contains the label will also be repainted.
Swing will usually determine a clipped area of the panel to be repainted. That is the rectangular area that contains the 3 labels will be repainted, not the entire panel.
Post a SSCCE that demonstrates the problem if you need more help.

How to let the user select an item from JOptionPane with a double-click

In my Java Swing application, I show a list of options to users using a JOptionPane with a JList, using the code below:
List<Object> options = getOptions();
JList list = new JList(options.toArray());
JScrollPane scrollpane = new JScrollPane();
JPanel panel = new JPanel();
panel.add(scrollpane);
scrollpane.getViewport().add(list);
JOptionPane.showMessageDialog(null, scrollpane,
"Please select an object", JOptionPane.PLAIN_MESSAGE);
How can I let the user select an option by double-clicking it?
JList doesn't provide any special handling of double or triple (or N) mouse clicks, but it's easy to add a MouseListener if you wish to take action on these events. Use the locationToIndex method to determine what cell was clicked. For example:
list.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
int index = list.locationToIndex(e.getPoint());
System.out.println("Double clicked on Item " + index);
}
}
});
I just need to know how to close the dialog after the user
double-clicks the item
In this mouse event, you can make use of SwingUtilities.windowForComponent(list) to get the window and dispose it using window.dispose() function.
See List Action for a solution that will allow you to select an Item from the list with the mouse or the keyboard.
In the Action that you create you can use:
Window window = SwingUtilities.windowForComponent(...);
to get the window that you need to dispose();

Dispatching event for specific component only in java

I would like to customize JTableHeader so it would offer serval actions (for example 2 buttons which one of them would sort column and second show properties of this column etc). Unfortunately it is not possible to set CellEditor for JTableHeader so i'm stuck with using mouse adapter. But maybe it is possible to dispatch event from this particular JTableHeader component so it will show up a popup menu which will contains all options i desire and it would dispatch event if option other than sorting would be chosen. This way standard JTable sorting operation will be available, along with my operations and it will maintain a decent visual apperance. So my question is - Is it possible and how it should be done.
In response to trashgod comment - i understand that you mean to treat defaultheader as an ordinary component and just use "add" function to add Components. It doesnt work well with JTableHeader. After reading trashgod example i wrote this:
private class mouseList extends MouseAdapter {
#Override
public void mouseClicked(MouseEvent e) {
TableColumnModel thisColumnModel = thisTable.getColumnModel();
int xCor = e.getX();
//int Cols = thisColumnModel.getColumnCount();
int thisColNum = thisColumnModel.getColumnIndexAtX(xCor);
int prevWidth=0;
for(int i = 0 ;i<thisColNum;i++)
{
prevWidth+=thisColumnModel.getColumn(i).getWidth();
}
int width = xCor-prevWidth;
/////////////////////////////////////////////////////////////////////////////////////
customHeader thisHeader = (customHeader)((JTableHeader)e.getSource()).getDefaultRenderer();
System.out.println(thisHeader.mainB.getText() + " text of thisHeader");
//////////////////////////////////////////////////
test thisTest = new test(null,false,thisHeader);
thisTest.setVisible(true);
///////////////////////////////////////////////////////////////
//System.out.println(width + " width of the header");
Object thisComp = thisHeader.getComponentAt(width, e.getY());
System.out.println(thisComp + "\n" + width + " + " + e.getY() +"\n" + thisHeader.getMainButton().getText());
((JTableHeader)e.getSource()).repaint();
if(thisComp instanceof JButton)
{
//System.out.println("sdfdsf");
String name = ((JButton)thisComp).getName();
if(name.equals("mainB"))
{
System.out.println("its working on main");
((JButton)thisComp).doClick(1000);
}else{
System.out.println("its working on menu");
((JButton)thisComp).doClick(1000);
}
}
((JTableHeader)e.getSource()).repaint();
}
}
MouseListener is applied to JTableHeader. HeaderRender is an extension of JPanel that contains 2 JButtons. Strange thing happens in line
Object thisComp = thisHeader.getComponentAt(width, e.getY());
When i left lines
test thisTest = new test(null,false,thisHeader);
thisTest.setVisible(true);
(This dialog shows selected component)
uncommented, function "getComponentAt" seems to work allmost fine (allmost because it never goes for else condition even when mouse is targeting second button, and it does not repaint clicked buttons[Strangely its repainting buttons in test dialog window]),otherwise it allways returns null object.
I dont know if it is important but i set Header renderer globally by invoking "setDefaultRenderer" on JTableHeader.
Im pretty much running out of ideas so i would appreciate any help.
This example shows the basic infrastructure, while this answer offers several important caveats regarding usability. This example shows how to change the RowFilter dynamically, but changing the RowSorter is similar. Both examples use JToggleButton to manage two states, but a JComboBox could be used to select from among more alternatives.

Simulating enter key in Swing (without using Robot)

So I'm trying to write a JButton that will act like an enter key when pressed. It must be able to fool a JTextField that is in focus into calling its action listeners. It can not use the robot framework, because that will make every program think enter is pressed, which is a problem.
Here is the backstory:
I have a program (written in Swing) which allows someone to enter data in many textfields and other things by hitting enter after typing in the data. It works great.
However, most people that use it are using a second program at the same time which automatically listens for an enter key and shuts off a robot (for those of you who are familiar with FIRST robotics, I'm talking about the SmartDashboard and the Driver Station). There have been quite a few complaints about this. People want to enter data without disabling the robot. As it turns out, the SmartDashboard (the program people want to hit enter on) allows custom swing components to be run along with it.
not entirely sure if I understand your requirement correctly (will delete this if not) ...
You can manually dispatch an event to whatever component you want to address. In the case of wanting to dispatch to the focusOwner
find the focusOwner by querying the KeyboardFocusManager
create a keyEvent with the focusOwner as sender
dispatch that event to the focusOwner
Something like:
Action action = new AbstractAction("fake enter") {
#Override
public void actionPerformed(ActionEvent e) {
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
Component comp = manager.getFocusOwner();
KeyEvent event = new KeyEvent(comp,
KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0,
KeyEvent.VK_ENTER, KeyEvent.CHAR_UNDEFINED);
comp.dispatchKeyEvent(event);
}
};
JButton button = new JButton(action);
button.setFocusable(false);
Action textAction = new AbstractAction("text") {
#Override
public void actionPerformed(ActionEvent e) {
LOG.info("I'm the text action" + ((Component) e.getSource()).getName());
}
};
JComponent comp = Box.createVerticalBox();
for (int i = 0; i < 5; i++) {
JTextField field = new JTextField(20);
field.setName(": " + i);
field.setAction(textAction);
comp.add(field);
}
comp.add(button);
Edit
added some lines for actually playing with it (#Joe commented it's not working). Clicking the button triggers the action of the focused textField (here simply prints out the field's name) Local context is vista and jdk6u27.
You might try getRootPane().setDefaultButton() on the frame. There's an example here.
Grabbing the element with the focus and manually dispatching an enter event didn't quite work, but because I just wanted to effect various JTextField, I came up with a similar solution:
addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
if (focusOwner instanceof JTextField) {
((JTextField) focusOwner).postActionEvent();
}
}
});
Thanks for pointing me in the right direction.

GUI won't refresh

I'm working on a textbased simple roleplaying game for my exame, but i have ran into some problems with my gui.
When the player registers, he can spend some attribute points in 3 categories. The gui is programmed to show the Raise Strength etc. button, if the player have any attribute points.
And that works cool, but then when the player clicks on a raise button, an attributepoint is taken for him, the problem is, that the gui doesn't seem to update.
if(Controller.player.getAttributePoints() > 0) {
JLabel attriL = new JLabel("You have " + Controller.player.getAttributePoints() + " unspent Attribute points.");
attriL.setBounds(110, 30, 250, 30);
hPanel.add(attriL);
JButton setStrB = new JButton("Raise Strength");
setStrB.setBounds(125, 60, 200, 30);
setStrB.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// tabbedPane.removeAll();
Controller.player.setAttributePoints(Controller.player.getAttributePoints()-1);
Controller.player.setStrength(Controller.player.getStrength()+1);
gameCtn.validate();
gameCtn.repaint();
System.out.println(Controller.player.getStrength());
}
});
hPanel.add(setStrB);
}
As you can see i have tried using repaint and validate on my container but with no luck, also i have tried on the Frame, and the panel, nothing seems to work?
Am i doing something wrong?
Thx
not clear if Controller... didn't invoked long timed and hard taks, basically (if you remove and then add new JComponents) to the GUI then you have to call
revalidate();
repaint();// not required on all cases
simple demonstrations what's happens, what's possible or most completed here
Sorry about that.
You have no code that says to make the button invisible.
public void actionPerformed(ActionEvent evt) {
...
if (whateverIsLeft < 1) {
JButton src = (JButton)evt.getSource();
src.setVisible(false);
}
attriL.setText("You have " + whateverIsLeft + " attribute points left");
}

Categories

Resources