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.
Related
is there a command that returns the componente associated to a speciefied String name in Java Swing CardLayout? I have many panels in my CardLayuot which are at first empty, at runtime i have to "update" those panels to add buttons in it (the panels already have GridBagLayout), i would prefer NOT to make panels all over again and replace the old ones, as it would be slower to charge, and instead get those panels and add something. Thanks guys! (i checked this but there's nothing like what i need https://docs.oracle.com/javase/7/docs/api/java/awt/CardLayout.html)
Every Component, such as JPanel, has a name field, and you can set it with setName(). If your program already has a List<JPanel>, you can search the list and check getName(). If not, you can add your panels to a Map<String, JPanel> and get() the one you want by name.
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.
I've started to work with Java Swing and I'm asking myself if it is possible to get elements on a generic JPanel, by Id or simply by name.
I mean something like 'getElementById("example")', used in javascript.
This is a little example, in pseudo-code of what I'd like to get:
....
myButton = my_panel.getElementById("xxxxxxx");
// OR BY VARIABLE NAME
myButton = my_panel.getElementByVariableName("xxxxxxx");
....
Is that possible in java?
You can use putClientProperty and getClientProperty as shown in below code:
JPanel jPanel = new JPanel();
JLabel label=new JLabel("Hi");
jPanel.add(label);
jPanel.putClientProperty("hiLabel", label);
System.out.println(jPanel.getClientProperty("hiLabel").getClass().getName());
Swing core has no concept of an Id for components. You can use setName() to set an unique name and then traverse the component tree of the container recursively to get the component with a certain name (Get a Swing component by name).
While Swing components can have a name (http://docs.oracle.com/javase/7/docs/api/java/awt/Component.html#getName()) this is not an id; it is up to you to ensure consistency.
This name property is not widely used. In SwingUtilities there is no method for finding a child by name, just an ancestor: SwingUtilities#getAncestorNamed.
You would have to to this by yourself. In general it is not impossible. You would start with a Container, iterate over its children (Component[] getComponents) and check for the name. Do this recursively for every child that is a Container itself. Break when found.
But this is untypical for Swing. The framework is not used declarative. (Other Java GUI toolkits are or can, like GWT or Android's native UI.) You would just store a reference to the component you create programmatically for later use.
Of course you can't search by variable name in Java. The name doesn't exist at runtime. Java works different than JavaScript. Most of the time it is not a good idea to directly transfer concepts from one system to another. You need to get used to each one to utilise it fully.
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.
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.