How to get text in two layered component - java

Please I hope that do not hurt your eyes after see the one... so sorry..
I want to get a text as I mentioned above.
Let's have a look at my terrible drawing...
What I want to do is :
I want to get the text from the yellow highlighed box.
I designed my program that I need to get few like the above. I used getComponentCount() to check how many labels there are. It is showing correctly and then I used getComponent(int n) , n = 0, and I was looking for getText().. but there is not.
Always thank you.

Your design is ok.
getComponent() returns a Component rather than a Label.
You just need to specifically cast it back as a Label:
String text = null;
Component c = panel.getComponent(i);
if (c instanceof Label)
text = ((Label)c).getText();
MVC Approach:
A more OO solution would be to separate your model (data) from the view (drawing).
You could create a new model Class, let's say "DrawingModel".
Then provide get()/set() for every property in the model.
You then connect both by drawingView.setModel(drawingModel).
When you need any data component, you can access or set it from DrawingModel class rather than directly from the View.
The component who actually "drives" the application is called the Controller.
The approach is an architectural pattern called Model-View-Controller (or MVC in short).
You can learn more here and here.

Related

Get text property from a Component

I have a JPanel called panelCreatePuzzle with 100 JButton's.
I used
Component[] cells = panelCreatePuzzle.getComponents();
To get an array of all the buttons. Now I want to print the text of each button. I have no clue how to do this. I tried the following:
for (Component cell:cells){
System.out.println(cell.toString());
}
Which does print something containing the text:
javax.swing.JButton[,321,321,30x30(...),text=here is the text,defaultCapable=true]
I can of course extract it from this string, but is there a more direct way that just gives me the text without anything else?
There are better ways to achieve what you're trying to do, but...
for (Component cell:cells){
if (cell instanceof JButton) {
JButton btn = (JButton)cell;
String text = btn.getText();
}
}
Basically, you need to determine if the component is actually a JButton or not and if it is, you can then safely cast it and work with it.
This is limited and a little brute force. A better approach might be to supply a getter which return an array of the buttons which represent the cells (rather then looking at all the buttons, which might include things you don't want).
Probably the best solution though, is to use some kind of model, which represents the current state, which can then be used to displayed through the UI and manipulated in what ever form you want in a de-coupled manner.
This reaches into a large array of concepts, including "model-view-controller" and "observer pattern", concepts which you should take the time to investigate and learn

ViewerSupport and ITableColorProvider or ITableFontProvider

I'm writing an RCP-Application and trying to use databinding to link the controls of the GUI with the model. This includes for example binding data to a table.
As far as I understood, org.eclipse.jface.databinding.viewers.ViewerSupport is the recommended method to bind a model to a table viewer. This will however only allow me to put the data as text into the table. I'd also like to change the foreground and background color aswell as the font of some cells, depending on other observables. I'd also be happy if I could somehow get a ITableFontProvider or ITableColorProvider into what ViewerSupport.bind(...) produces.
So far I've not found a nice way to do that. I could copy the contents of ViewerSupport.bind() and override the LabelProvider with my own class. This seems a bit messy.
I could also after calling ViewerSupport.bind retrieve the LabelProvider and replace it with a delegating LabelProvider which also implements ITableFontProvider and ITableColorProvider. This leaves me creating a lot of methods that do nothing but delegate things to another object. Not very elegant aswell.
All of that doesn't seem so nice. Any idea how to do it in an elegant way? Am I overlooking some factory class to do that?
ViewerSupport just provides simplified methods based on the various data binding content and label providers. It is perfectly acceptable to use these content and label providers directly when ViewerSupport does not provide what you want.
For example, ViewerSupport.bind(StructuredViewer viewer, IObservableList input,
IValueProperty[] labelProperties) is just:
ObservableListContentProvider contentProvider = new ObservableListContentProvider();
if (viewer.getInput() != null)
viewer.setInput(null);
viewer.setContentProvider(contentProvider);
viewer.setLabelProvider(new ObservableMapLabelProvider(Properties
.observeEach(contentProvider.getKnownElements(),
labelProperties)));
if (input != null)
viewer.setInput(input);
So you could just use this code but with a sub-class of ObservableMapLabelProvider with your font and color providers.

Java swing - creating text field on button's place

When specific action is performed, I want to replace button with text field. I know that I have to call button1.setVisible(false); but I don't know how to create text field on the exact same place. I am using NetBeans designer, if you can give me a hint, how to add 2 components at same place, and switch between then, something like switching between layers in photoshop, if something like that is possible, would be great. Thanks
For many components in one space, use a CardLayout as see in this short example.

Java swing design : static vs instance

I have designed an html document editor and I wanted some help in resolving a design problem in it. The problem is as follows -
The document editor consists of a surface (JFrame) and a menu bar. Inside the surface I have three panels - a tool panel, text panel and status panel (which are all extensions of JPanel). The text panel has the customized text pane (extension of JTextPane). Now the problem is that - there are lots of scenarios where the menus and the widgets items on the tool panel need access to the underlying document model of the JTextPane. E.g. to implement list/paragraph dragging functionality, the ruler needs to know the position of the caret inside the document model, so that I can mark the paragraph whose left inset I need to increase.
The way I have organized my design right now is that - surface is a singleton, so to access the html document model inside the JTextPane you need to code your way through the following maze -
Give me surface -> go to text panel -> go to text pane -> go to document of the text pane
Another alternative to make the reference of the document inside the text pane static, so that it can be accessed directly.
TextPane.getTextDocument ()
Also the html document inside the Text Pane I am using is not customized right now. So I am just using the default HTMLDocument returned by the text pane. Though in future I may have to replace it with a more customized extension of HTMLDocument (e.g. to implement cusom tags)
I am somewhat of a design novice. Can some design guru throw some light/insight into this?
I think if you get 10 responses you'll get 11 answers. :-)
First, there is no need for a Singleton. In this scenario, it's just a way of cheating with a global variable. And what happens when you want to have two or three text documents open?
Do your menus have ready access to the tool panel? Since toolpanel is a sibling of the textpanel, and in a 1-1 relationship (I think?) it is somewhat "reasonable" for toolpanel to know about textdocument (have a link it) and a convenience method, getTextDocument(). And it seems reasonable for your widgets to know about their immediate parent, the tool panel.
That would be my way of approaching the problem - what links between objects "make sense". You want as little coupling as possible, but there are places where you do need coupling. Maybe I have misunderstood your problem, or maybe you think a lot differently than me, in which case you should do it another way. Also, you are making a best guess as to how your code might evolve in the future. Good luck with that! :-)
One big question for any solution - does the text document change? (e.g., is there a File->New menu or a File->Open menu?). If so, that needs to be considered. In my proposal, the JFrame, on a File->Open, would create the text document and then change the link to it in the ToolBar.
p.s. MVC purists - please add appropriate models and controllers! I just talked about the graphical components to keep things simpler...
p.p.s. Examples of "thinking ahead" for reasonable enhancements
Would this handle multiple JFrames open at once? Yes.
Would this handle a single JFrame, but with multiple documents (say, a tabbed interface for the text document)? Almost. The method has to be a little smarter to know which of the many documents is active, but you can easily imagine doing that.
How about when I need to hold a lot more info about the dicument, like the name (so Save gives a good default), last time saved, is it "dirty", is it HTML or XHTML or whatever... At this point, you'll probably want to add one more model layer. But you can sortof imagine, with one more layer of indirection (one more link) this being o.k. So it depends on how close you are to implementing #3 how you want to design.

Reset/remove a border in Swing

Here's a very specific coding question:
I've recently been asked to maintain some old-ish Java Swing GUI code at work and ran into this problem:
I've attached my own subclass of InputVerifier called MyFilenameVerifier to a JTextField (but it may as well be any JComponent for these purposes). I've overridden the verify() method such that it calls super.verify(input) (where input is the JComponent parameter to verify()). If super.verify(input) comes back false, I do:
input.setBorder(BorderFactory.createLineBorder(Color.RED));
This is a convention used throughout the UI of this application that started long before me, so I don't have a lot of choice as far as using other ways to get the users attention (wish I did). This is just the way it works.
Problem is, once the user goes back and types something valid into the text field, I need a way to set it back to default border (instead of just saying set it to Color.GRAY or whatever, which is a different color from its original border). I need a way to say, "remove the extra decoration and go back to normal" or just set the border to its default, in other words.
Couldn't you just call input.getBorder() and cache it somewhere before setting the border to red?
Or without caching anything, you could tell the JComponent to update its UI back to the look and feel's defaults via component.updateUI. That should make the component reset its colors, borders, fonts, etc to match the original settings.
input.getBorder()
Wouldn't it be awesome if no one ever saw this and I got away free without the ass-beating I deserve for asking this question?
Not sure how your system is build, but I think you can store the original border before changing it. So you can change it back later
// assuming the Border was not null before
if (!super.verify(input)) {
original = input.getBorder();
input.setBorder(...);
} else {
if (original != null) {
input.setBorder(original);
original = null; // not needed
}
}
You need to preserve the existing border when you change it.
One way to do this is to use the methods putClientProperty() and getClientProperty(), which you'll find documented in the API.
Another possibility, if there are only a few input widgets you need this for is to subclass, e.g. JTextField, add setBorderOverride() and modify getBorder() to return "overriddingBorder" if it is not null.
Then you just use setBorderOverride(redBorder) to make it red and setBorderOverride(null) to clear it.
This of course depends on the painting to use getBorder(), which it may or may not do, and which may be implementation specific.
Incidentally, you only need a single static reference to the border-- it's the selfsame border instance used by all JTextFields.

Categories