I'm new to Java and programming. I want to generate an int in a JDialog class by selecting a row in a table and send that int to the main class which created it, or, to handle the button action performed in the main class. Main class creates the subclass here:
private void launchtable() {
DlgBeds dcl = new DlgBeds();
dcl.setLocationRelativeTo(this);
dcl.setVisible(true);
// I want in this place to put something like this:
txtCode.setText(subclassgeneratedint );
}
But first I need to get that int from the subclass., I tried creating a method there that I can use in main to return the int, but it instead sets the text with the first row selected (the default selection), and it can't return more row selections to keep changing txtCode; the method like just dies there.
The main could also have an action performed for the button in the subclass but the parameter would need to be one from the subclass I guess.
protected void actionPerformed[button in the subclass](ActionEvent e) {
//actions
}
I'm really lost, I know I need to study more to solve situations like this but I needed the answer as fast as possible.
Add a ListSelectionListener to your table. You can get the selected row as shown here and pass it to your main window using a PropertyChangeListener as shown here and here.
Related
I know how to write a ChangeListener that records the index of the newly selected tab in a JTabbedPane, but what I want is to detect when a user leaves a certain tab. I have 7 tabs, and I would like to run some code when the user leaves tab number 6. How can I accomplish that?
Try using the focus state. You can check with component.hasFocus() or the getSelectedIndex method. This depends on how your components are accessible or how you implemented your TabbedPane
I found the solution here:
Java JTabbedPane - Action immediately before changing the selected Tab.
All I had to do was create a new class that extended DefaultSingleSelectionModel. The class overrides the setSelectedIndex() method.
public class MySingleSelectionModel extends DefaultSingleSelectionModel {
#Override
public void setSelectedIndex(int index) {
if (getSelectedIndex() == 6) {
//perform action here
}
super.setSelectedIndex(index);
}
}
Finally, I set the model in the JTabbedPanel:
myTabbedPane.setModel(new MySingleSelectionModel());
I am trying to implement a feature in a project that I am working on but I am having dificulties. The project allows the user to create 3 different objects that all share the same super class. Each object is part of an arrayList and is represented by an ImageIcon inside of a JLabel. I would like to be able to click a specific JLabel and open a message dialog with a toString() method that returns information about the coresponding object.
So far, I have a (poorly implemented) system in place that will allow the user to click any ImageIcon but it will only display information about the most recently created object. I am aware why this code only displays the information it does but I do not know how create the code that I need.
If anyone can help I would be very grateful. If anything is poorly explained or needs elaborating on, please ask. I have attached my current code below, Thank you.
Code explanation: The 'count' variable is used to count the number of objects created (I cannot have more that 9). I know that the current code will just display the 'count-1' object created (which is the newest one). I'm just un aware of what I need to do to find the specific object relating to the lable that is clicked.
label[count].addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e)
{
JOptionPane.showMessageDialog(null, myAppliances.get(count-1).toString());
}});
Each object is part of an arrayList and is represented by an ImageIcon inside of a JLabel.
That gives a good hint to it. How about doing following
Class MyObjectLabel extends JLabel something like below:
public MyObjectLabel extends JLabel
{
private YourObjectThatisInList localCopyOfObject;
public MyObjectLabel (YourObjectThatisInList object)
{
super(createIconForTheObject(object));
this.localCopyOfObject=object
}
//add getter setter method for localCopyOfObject
}
2) Now add listener to this class.
3) On event fired of this new Label class, call the getter for localCopyOfObject and display the toString for your localCopyOfObject stored in MyObjectLabel.
Please note that createIconForTheObject, is just a placeholeder method I showed. You can use your own method to create icon
Thanks
It might be confusing for some to answer this but I will try to put my question in the best way. I am working with jdbc and gui. Basically I want to display (in buttons format) the particular data received from my sql database. I could get the data correctly and put it to my array of buttons as their names. In other words, I have an ArrayList of buttons with different names/texts received from my database. Thus i really need to make an arraylist of buttons since data are dynamically populated. My problem is, I am so confused of how am going to create an actionListener to each button. Everytime each button is clicked, it must show the values associated with its name. I don't know how am i supposed to pass at least the names of the buttons to my actionListener method (or action Event Handler). If you find it confusing, here is the code for my buttons.
todayTaskButton.add(new JButton(taskForToday.get(i)));
todayTaskButton.get(i).setPreferredSize(new Dimension(300,75));
todayTaskButton.get(i).setBackground(Color.GRAY);
todayTaskButton.get(i).setFont(new Font("Century Gothic",Font.PLAIN,30));
todayTaskButton.get(i).setForeground(Color.WHITE);
todayTaskButton.get(i).setFocusable(false);
Thank you so much
You don't need to pass the name of the button to the ActionListener. It is automatically detected. You just need to implement the method actionPerformed(ActionEvent) in you class.
Then add the listener to the button :
todayTaskButton.get(i).addActionListener(this);
In your actionPerformed method, you can do:
JButton b = (JButton) e.getSource();
String text = b.getText();
Honestly there are so many ways you might achieve this, the problem is picking the right one for you...
You could...
Create a anonymous class for each button, each time your create them
todayTaskButton.get(i).addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//...
}
});
While this can work, it can make the code really messy, you also still need a way to map the action back to the button in some way, which can be done using the actionCommand property or using the source property if you don't mind iterating through the list of available buttons
You could...
Create a purpose build class which implements ActionListener for each button, which possibly takes some kind of reference to the data
todayTaskButton.get(i).addActionListener(new TodayActionListener(taskForToday.get(i)));
This is a little more focused, as you don't really care about the button, as you have the "today" value for the listener, so all the normally repeated code could be isolated into a single class and you would simply pass in the "variable" element
You could...
Take full advantage of the Action API and make individual, self contained actions for each button...
public class TaskAction extends AbstractAction {
public TodayAction(String task) {
putValue(NAME, task);
}
#Override
public void actionPerformed(ActionEvent e) {
// Specific action for task
}
}
Then you could simply use
todayTaskButton.add(new JButton(new TaskAction(taskForToday.get(i))));
While this is similar to the previous option, the Action is a self contained unit of work and has a number of properties which the JButton can use to configure it self. The Action can also be re-used for JMenuItems and key bindings, making it incredibly flexible
Have a closer look at How to Use Actions for more details
I am trying to program a java application that consists of several windows using JFrame.
Each JFrame contains a JTextField and buton to go to the next JFrame.
I need to retrieve all the information entered by the user at the end.
I created an event click on the buton to save to a public class all the data that the user introduce in the JTextField. I named that public class myData, which has a static attributes.
The problem is that I can not access this class from the button listener function.
I get an error: cannot refer to an non final variable inside an inner class defined in a different method.
My goal is to be able to share the class myData between different methods of a different class.
E.g. I have a class named myClass1 and myClass2, so I want to share the myData attribute between myClass1 methods and myClass2 methods.
Please anyone can someone help me? or propose another way to do this!
Thanks in advance !
All of the calls about MVC etc. are valid, but this isn't that hard.
What you want to do is in your Main, you can create your Data (Model) class, the class that holds all of your information.
So, you can do something like this:
public class F1 ... {
private final Data myData;
public F1(Data theData) {
myData = theData;
}
....
}
public class Main {
Data myData;
public static void main(String args[]) {
Main m = new Main();
m.setMyData(new Data());
F1 f = new F1(m.getMyData());
...
}
}
Then, later, when F1 calls F2, simply do the same thing -- create F2 with the Data passed in earlier by the constructor. That way, as each Frame runs its course, they're all working on the same instance of Data. When all is done, the single instance of Data is left within the Main class for you to do with what you will.
There are better ways to reorganize your entire program, but this should give you ideas on how to get over the hump you're having right now.
Addenda:
There are several things you can do.
When your get the ActionEvent, it contains a source. That source is the component that generated the event (most likely a Button in this case). If you know where the button is located in the hierarchy of things, you get to your Frame directly. In the pastebin example, you have Frame -> Panel -> Button. So, if you have the Button, you cat get to the Frame.
public void actionPerformed(ActionEvent e) {
JButton sourceButton = (JButton)e.getSource();
F1 f1 = (F1)sourceButton.getParent().getParent();
Data myData = f1.getMyData();
data.setField(...);
}
Again, this is not the recommended ways of doing things. The tutorials have decent examples of using MVC and property change listeners and the whole kit. But this should get you to where you want to go.
Sorry, but your design needs alot of work. I'm going to recommend you read up on MVC. it may seem like alot to chew on right now but it will help you immensely in the long run. On a side note, dont nest your data class definition(s), and remember to always distinguish between classes and objects.
Your overall design of swapping JFrame's seems a bit iffy to me. Why not instead use either dialogs such as a JDialog or JOptionPane or even better a CardLayout to swap views. Also I urge you not to use static fields for any of this as this can cause significant problems in the future and makes your code less compliant with good object oriented principles. With regards to information sharing, about all I can say is that it's all about one class having the proper reference to the other class. For more specific advice you'll likely need to show us more information and code.
Edit
Also, you know of course that you can get a reference to the JButton that stimulated the ActionListener by calling getSource() on the ActionEvent object passed into the actionPerformed method. This may allow you to get a reference to the class that holds the JButton if necessary.
I am trying to implement a ListSelectionListener for some of my JTables. Simply (at the moment) the ListSelectionListener is supposed to simply return the text of the cell that was selected.
My program design has several JTables and I would like to have one ListSelectionListener work for them all. In the valueChanged event of the ListSelectionListener I thought it was possible to do something like:
private class SelectionHandler implements ListSelectionListener {
public void valueChanged(ListSelectionEvent e)
{
JTable table = (JTable)e.getSource();
String data = (String) table.getValueAt(table.getSelectedRow(), 0);
// Print data
}
}
Behind the scenes I have used the following code to get the SelectionHandler working with the table in question:
fbTable.setCellSelectionEnabled(true);
ListSelectionModel cellSM = fbTable.getSelectionModel();
cellSM.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
cellSelectionModel.addListSelectionListener(selectionHandler);
When I run the program I get a ClassCastException error:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.DefaultListSelectionModel cannot be cast to javax.swing.JTable
at cardboardfantasy.CardboardFantasyView$SelectionHandler.valueChanged(CardboardFantasyView.java:360)
// This is the line in question: JTable table = (JTable)e.getSource();
Is there a way to do something like this? One solution I thought of was to compare the source of the event (e.getSource()) to all my JTables to see if they were equivalent (big if block) and then just calling .getValueAt inside that block but that would making the code in the future difficult if tables were to be added or removed.
Either debug your code in your IDE, set a breakpoint and see what the type of e.getTarget() is:
Object source = e.getSource();
JTable table = (JTable)source; // breakpoint on this line and inspect the variable 'source'
String data = (String) table.getValueAt(table.getSelectedRow(), 0);
Or if debugging is not possible for whatever reason do this:
Object source = e.getSource();
System.out.println(source.getClass());
But: debugging using System.out.println is evil. your debugger is your friend.
As the error implies, the source object in question is a DefaultListSelectionModel not a JTable. This makes sense since the source of the event (that is, the object which fired the event) was the selection model object, not the table. Also, models in themselves make no assumptions about what type of object is using them as a model so there is no way to get a reference to the table via the selection model.
Pass the JTable instance to your selection handler. As long as the handler listens on one table, you'll be able to use that instance instead of relying on the information from the event.
I think there are two main solutions:
Use a JList and register the listener not with model but directly with the list. Then, if the list is contained by a table you could just ask for the list's (Component) parent to find the responsible table
Override DefaultListSelectionModel to (for example) take an additional argument in the constructor, which would be a JTable instance (every table will need a new instance of that model). You would save that instance in an instance variable and could then operate directly on the table when an event occurrs
I do not think that either of these solutions is ideal. I have the feeling that you could make your life easier by using some pattern or idiom to get around having to know which table the source was. But to give you any clues there we'd have to see a lot more of your code.