Wicket: Component to reference model from containing Panel - java

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.

Related

Creating custom JList that runs method other than toString for Objects

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.

Using just one Custom Renderer for several ComboBoxes

I am currently working through the "Providing a Custom Renderer" example on this page. And now I wanted to create more than just one of these boxes. I did this by creating six renderer classes, one for each box.
And now for my question. Is it possible to just have one renderer class for all six boxes? For that purpose I tried to parse two variables to the constructor of the CustomBoxRenderer, like this.
public ComboBoxRenderer(ImageIcon[] currentImage, String[] currentString)
But due to how the programm seems to work, the currentImage array is null until a certain point, so I get a exception.
But let's assume this would work how I expected it to work, I still would have to create six seperate instances of the renderer for each box, which I'd like to avoid aswell.
I hope this is enough information, I could also provide my full code, but I think that'd be too much for this page here, if not, let me know.
If i'm reading correctly you could create a class that extends combobox and just adjust it so that it automatically uses your custom renderer, then all you have to is create a normal instance of your custom combobox and use it as normal except it will use your renderer without any hassle.
e.g. in your constructor you would just have this line
this.setRenderer(new ComboBoxRenderer(currentImage, currentString));
Im unsure why you think you would need to create six instances as the renderer deals with each box.
Hope this helps.

can Java Swing JPanel Hold a String Value?

Can a Java Swing JPanel hold a String value than can be modified/accessed where I can save some information?
I see no other option but to implement my own class holding a JPanel and a String... was just trying to save some space/coding..
I like the setName/getName of the Component super class... is there any inconvenience in using that ??
Yes it can. Any Swing component can hold client properties for the specific component.
See the putClientProperty(...) and getClientProperty(...) methods of JComponent. Using this approach you can define any number of client properties:
panel.putClientProperty("Title", "Panel1");
panel.putClientProperty("Description", "some text for the description");
You can also use the setName(..) and getName() methods if you just want to uniquely identify the panel with a string name. Many IDE's will use this property.
Of course if you are creating a panel with multiple Swing components and related instance variables then you would probably extend JPanel and customize its behaviour.
I like the setName/getName of the Component super class... is there any inconvenience in using that ??
If you feel the "name" property adequately describies the data you want to store then this is the most efficient way to store the data. However, if the data is not really the name of the component then don't force the data just because it is easy to use. Also it is possible some IDE's may use this property for generic debugging or messaging. That it may check display this value in an error message to help identify a specific component.
Several solutions, and it's hard to know what you're looking for here. You could create a MyJPanel class that extends JPanel and is identical except including a String field with getter/setter. You could also store information in silly ways like by setting/getting the name of the JPanel. (That is use setName and getName of the Component superclass.) Another solution is to add a JLabel or some other component with that information to the JPanel, and if necessary, making it invisible or hidden.
No, I think it cannot hold a String value.
You can see all getters/setters here:
http://docs.oracle.com/javase/7/docs/api/javax/swing/JPanel.html
Also, you can check the source code (if you want to go that far).
There's no getter/setter useful for holding a String value
(I mean ... e.g. no setText or setTitle).
Of course, you can add e.g. an invisible JTextField to your JPanel and
set the String into the JTextField. But that doesn't seem very nice to me.
JPanels hold JComponents, i.e. JButtons, JLabels, etc. A String is not a component. It would be best if you'd just use a JLabel with a String as its parameter, then add that to a JPanel.
You can add a Component like JLabel/JTextField and use setVisible(false). That object can hold strings.
note: Only for Buttons.
You could use setAtionCommand() but it is indented for something very specific. It would be horrible practice for anything else.

JFrame in java jframe.add(button);

I have to write: jframe.getContentPane().add(button);
But I found out that it also works when I only write
jframe.add(button);
What are the differences between the two approaches? Is it favorable to write JFrame.getContentPane().add(button); ?
It a matter of taste. I always use getContentPane().add(..), as I think it is easier to read / know what's actually going on
Try this........
Before the arrival of Java 1.5, jframe.getContentPane().add(button) was Used..... and thats was the legal way of doing it....
But then from Java 1.5 and onwards, included the myframe.add(button)... as also one of the legal way of doing it.. Its just like, accessing the static variable with the Classname is the legal way of doing it...but still you can access the static variables using the class instance...
The class javadoc of JFrame is rather clear on this
The JFrame class is slightly incompatible with Frame. Like all other JFC/Swing top-level containers, a JFrame contains a JRootPane as its only child. The content pane provided by the root pane should, as a rule, contain all the non-menu components displayed by the JFrame. This is different from the AWT Frame case. As a conveniance add and its variants, remove and setLayout have been overridden to forward to the contentPane as necessary. This means you can write:
frame.add(child);
And the child will be added to the contentPane.
So you should know that elements like JButton, JTextArea etc. should be added to Container and your method:
getContentPane()
returns the Container object for this frame. So both approaches work same but second approach you should use.
In the case if you will have big application with many elements first approach is less readable and second is generally recommended.
Difference isn't:
Jframe.add() - Appends the specified component to the end of this container. This is
a convenience method for Container.addImpl.

How to get access JTable from another class java

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

Categories

Resources