I have three classes one is a JFrame and other two are JPanel . The class A has a JTable and i need to access the JTabel selected item in another class. Is that possible to get the selected item using the model? Or how to access the JTable in class B?
Just because you are working with a Swing GUI does not change any of the rules of good object-oriented program techniques. You will need to give classes provide means of communicating with each other, perhaps by getter or setter methods, but you will want to limit this communication to be done with the least exposure necessary to maintain encapsulation/data hiding.
You can access the selected item in the JTable in any class, including class B, that has a reference to the JTable, its ListSelectionModel, or something else that exposes the selected item.
For example, if class B has a reference to class A -- and class A has a JTable -- then class B could ask class A for the currently selected item.
Please , your jTable variable accees modifier replace as a
Related
In the game I'm trying to create, I have a class which displays the inventory for a character in a JList. I understand that populating a JList with Objects will cause the toString method for that object to run when the JList is actually displayed. I want to create a custom JList that does something other than run the toString method on the Objects populating it. I understand that I can overwrite the toString method on Objects, but I need the toString method to be different than what's displayed in the inventory. For some reason, I'm unable to view classes such as Object or JList (I can still view my own), otherwise I'd look through the code myself. (TL;DR - I need to overwrite the method in JList that runs toString on the objects populating it)
Side note: only a specific type of Object will be put into the JList, so I know what I intend to run instead of toString, and the custom JList will only be used in 1 class.
The correct way to do this is with ListModel. For details, read the official tutorial on How to Use Lists. Pay close attention to the section on Creating a ListModel.
Maybe simplest way is to make a sub class from JList - a new class extends JList - and add the method(s) you need and use it instead of JList .
I managed to find the answer for myself. A custom class must be written extending JLabel implementing ListCellRenderer<>. In this, you can specify exactly what goes into the text component of each cell in the JList.
(A general Question)
I have an assignment in which I have to build a sudoku and I thought about the classes/logic to build it and thought I could use an advice.
I want to use a JFrame and build on it a JPanel with TextFields (the user is supposed to "solve" the sudoku).
I have a class called "DrawSudoku" which draws an empty board. I have to draw an empty board first, so the "user" can type numbers in it.
On that board I have to check some logic. So I have to access the textFields themselves.
So far that's all I've done. Now I am thinking about building another class with the "logic" behind the board.
But I've encountered a problem
How do I get the JTextFields that exists on the JPanel, from another class?
Can I have separate classes for the Drawing and Logic Behind it?
Thanks!
On that board I have to check some logic. So I have to access the textFields themselves.
Not necessarily
How do I get the JTextFields that exists on the JPanel, from another class?
How do you assess the state of any object from another object -- via an accessor or "getter" method.
Can I have separate classes for the Drawing and Logic Behind it?
Not only can you, you absolutely should.
If this were my project I would consider doing the following:
First and foremost, create a non-GUI Sudoku model class. This could include:
SudokuCellValue enum (name it what you want), an enum that can hold a value from 1 to 9 as well as possibly an EMPTY value (although you could use null to represent this)
SudokuCell objects, ones that have boolean editable, and holds a single value to the above enum.
SudokuGrid object, a 9 x 9 grid of SudokuCells.
A mechanism to hook listeners into the model so that they are notified of changes in state -- i.e., changes in the SudokuCellValue held by one or more SudokuCell objects. The View (the GUI) will be one of the major listeners to this model, and will change its display when the model's state changers.
I'd create a View class, meaning the GUI,
One that holds a reference to its model (see above)
and one that has attached listeners to its model -- I like to use PropertyChangeListeners for this
I'd hook it up with a grid of JTextFields,
These text fields would use a DocumentFilter to allow the user to either clear the field or enter only 1 through 9 single digit numeric text.
Would be enabled for input (or perhaps better -- focusable for input), based on the editable state of the corresponding model cell.
I'd create a Controller that would control some of the communication between the view and model.
With this type of set up, outside classes could listen for changes to the model and wouldn't have to have any access directly to the JTextFields of the view.
You don't need to have access to the text fields themselves if you include public methods in your DrawSudoku class that your logic class can then call. This would be very similar to writing getter and setter methods for private variables. For example, if you wanted your logic class to be able to write the number "6" into a certain square on the board, you could write a method in DrawSudoku like this:
public void setSquareText(String text, int row, int column) {
// change the appropriate text field here
textField.setText(text);
}
Then, call this method in your logic class, by making an instance of the drawing class:
DrawSudoku drawer = new DrawSudoku();
drawer.setSquareText("6", 1,1);
Alternatively, you could write a method in DrawSudoku that returns a given JTextField, like this:
public JTextField getTextField(int row, int column){
// find the appropriate text field, then return it
return textField;
}
Then, call this method in your logic class to get access to the JTextField, like this:
JTextField textField = drawer.getTextField(1,1);
textField.getText();
textField.setText("6");
I have a list of items that are pulled from a database, it combines the various fields with a rs.getString method to create a longer string of items, this is done in an action button method.
I would like to be able to click on an item in this list and have one of the fields display as text in a textbox, so this needs to be done through the list selection event method where I instruct the program to set the text to my desired value.
My problem is, I am not sure of the logic to follow in order to specify how to retrieve that fields information that will be corresponding to the item that is selected in the list, can you give me any ideas?
Rather the combining the fields into a single String, create a POJO (Plain Old Java Object), which provides getters (and possible setters) for the fields you want and these objects to the ListModel
Use a ListCellRenderer to customise the way which the JList renders the POJO the way you want to. See Writing a Custom Cell Renderer for more details.
When the user selects an item from the list, use JList#getSelectedValue and cast to the same class as your POJO. You can now use the POJO's getters to extract the properties you want to display.
The idea is to generate a self contained unit of work, which, based on what you want to do, you can customise how the object is displayed.
This concept is a corner stone to the separation of data (model) and the UI (view) behind the Model-View-Controller paradigm and OOP generally...
To illustrate my problem, let's say I have an instance of Thing which has two text properties - 'foo' and 'bar'.
I want to create a Panel to edit instances of Thing. The panel has two TextField components, one for the 'foo' property and one for the 'bar' property.
I want to be able to call setDefaultModel() on my Panel with an instance of IModel<Thing> and for the TextField components to reference this model. How best to achieve this?
Should I override the Panel.setDefaultModel() method to also call setModel() on the two TextField components? Or perhaps create anonymous ReadOnlyModels for the TextField components, overriding the getObject() method to retrieve the object from the containing Panel's model?
Neither of these seem very elegant to me, so I was wondering if there's a better way?
You can use a PropertyModel for the textFields. Pass the IModel<Thing> into the constructor of the PropertyModel with foo as the property name:
add(new TextField("fooFieldId", new PropertyModel(thingModel, "foo")));
The PropertyModel will figure out that the thingModel is a Model and call getObject().getFoo() etc.
This assumes the IModel<Thing> instance doesn't change, only its underlying object which can be changed calling setDefaultModelObject.
Maybe I'm just missing the point, but I can't find a Panel.setModel() in the JavaDocs of neither 1.4 nor 1.5. If it's something you implemented maybe you could change it not to replace the model object but to call model.setObject() instead?
Disclaimer: Can't really check right now, cause there is no wicket at work and my home machine suffered a video card breakdown earlier...
Maybe this would help?
public abstract class AbstractWrapModel<T> extends Object implements IWrapModel<T>
Simple base class for IWrapModel objects.
See IComponentAssignedModel or IComponentInheritedModel so that you don't have to have empty methods like detach or setObject() when not used in the wrapper. The detach method calls the wrapped models detach.
Till now, I have developed simple swing applications so there was no need to break the GUI code into diff. classes but as this application is going to be very large, I decided to break the code into diff. classes so as to make the code more manageable.
But before proceeding, I have some doubts in my mind which are as follows:
Brief description of GUI
It will have a main JFrame (MainFrame). On that a JPanel(MainJPanel) is set whose layout is to be CardLayout. It will contain 25 cards (each card is in the form of JPanel which contains its own swing components).
Q1. I have decided to make 25 classes (each for one JPanel card). Is it correct approach?
Q2. If the above answer is correct, then how can I write code of xxxxActionPerformed() methods of buttons which are on those cards (25 cards) as these methods need access to the object of MainJPanel
e.g.
public void buttonActionPerformed(ActionEvent evt) {
java.awt.CardLayout c = (java.awt.CardLayout) mainJPanel.getLayout();
c.show(mainJPanel, "card1"); // card1 is this card
mainJPanel.updateUI();
}
I googled for swing examples but almost all of them shows the use of diff. swing components. Can you also please suggest me a link that shows some swing examples that contain GUI codes in diff. classes.
Q1) That sounds like quite a lot of classes. While it's possible that each class has distinct functionality I find it more likely that you could combine some of those into more common classes. For example instead of YellowCard and BlueCard you could simply have ColorCard where color is a parameter.
Q2) Model View Presenter (MVP) and Model View Controller (MVC) are two (or one, depending on your view) common design patterns which help design GUIs so that everyone has the data they need.
More specifically, you might not need all cards to have a reference to the parent panel. For example, if you have a BurgerPanel which allows the user to order burgers and a StatusPanel which shows how many burgers have been ordered you can communicate between them as follows...
Create a StoreStatus object and pass it to both BurgerPanel and StatusPanel. When the user orders a burger with burger panel it updates the store status. The store status notifies the StatusPanel of this update via the observer pattern and then the StatusPanel reflects the change.
UPDATE: In regards to your specific example you would either some kind of reference to the parent class or you could notify it of updates with the observer patterns. (The advantage of the observer pattern is that any changes to the parent class couldn't create changes in the child classes.)
I would say you are correct in creating a class for each card. This is a logical way to split up the code.
If you need to reference the MainJPanel then simply pass it into the constructor of each card class and keep a reference to it.