isShowing() vs isDisplayable() - java

What is better to use:
.isDisplayable()
or:
isShowing()
to check if JButtons are visible, but also for other things? Also what is the difference between them? At this moment they look like same thing to me, but i'm a beginner.

they are giving same results, even when button was set to Opaque(false)
Don't confuse opaqueness of a component with visibility of a component.
Opaqueness is for painting the background of the component.
The component can still be visible even if the background is transparent.
Try using setVisible(false) to see the difference between the two methods.
A component can only be showing if it is:
displayable
visible

Related

Why do I have to use setvisible() on my JFrame when I change components?

So for the sake of simplicity I set up a little test code just to figure out this problem. Basically I have a JFrame and I added 'this' to it (I just extended my main class from JComponent to save time). this component fills in a red background. Then I have it sleep for 2 seconds and then type this.
f.remove(this);
thing t = new thing();
f.add(t);
f.setVisible(true);
f being my JFrame object and 'thing' is just another class extending JComponent that paints a blue background..
when I comment out setvisible() it no longer changes to blue.. I've tried using t.setVisible(true) but it seems I have to make the frame visible again, not the component
does anyone know why I have to call that... or if there is another way to change components within a single frame?
"Basically I have a JFrame and I added 'this' to it (I just extended my main class from JComponent to save time). this component fills in a red background. Then I have it sleep for 2 seconds and then type this."
Don't "sleep" your program. Instead use a java.swing.Timer to perform repeated tasks on the GUI or for animation. See more at How to Use Swing Timers. You can see a bunch of Timer examples here and here and here and here and here
Instead of trying to add and remove panels look into using a CardLayout which allows you to switch between views. It will help you avoid a lot of problems that come with with adding and removing components/containers. See more at How to Use CardLayout. Also see a simple example here.
To answer your main question, whenever you remove and add components from your frame, you need to revalidate() it. setVisible() takes care of that for you.
Side Note
Seems like a lot adding an removing background panels) just to change the background. Why not just setBackround()? You can switch colors with the use of the Timer
Calling setVisible(true) makes the frame appear onscreen. Sometimes you might see the show method used instead. The two usages are equivalent, but we use setVisible(true) for consistency's sake.

Does isVisible() guarantees the visibility of the UI object in JAVA

Its generic question. If I add some UI objects such as JButton etc and check the isVisible property, it would return true. However, does it guarantee that the object is actually rendered and visible correctly on the display? If not, is there some better way to check the same?
No isVisible() is only a hint for this component itself. If it is really visible for the user depends on the parent hierarchy of the component. This can be verified best by isShowing() inherited by Component, which checks isVisible() and isDisplayable() of the component and all it's parent components. But as the javadoc mentions even that does not really guarantee that the component is really really visible to the user:
Note: sometimes there is no way to detect whether the Component is actually visible to the user. This can happen when:
the component has been added to a visible ScrollPane but the Component is not currently in the scroll pane's view port.
the Component is obscured by another Component or Container.

Overriding the paint() method in JButton

I have a class that extends JButton because the custom look and feel I'm using ignores the isOpaque() call. What I mean is, the background of the button is rendered even though I have called setOpaque (false) on it and all parent panels. I have confirmed that this is an issue with the LAF from the companies design people so there is nothing I can do but extend the class.
So my question is, how can I implement the paint() method to not render the background and just the button icon?
Cheers
SOLVED: The answer I was after in case anyone is interested was to use button.setContentAreaFilled(false);
Painting is done by three methods: paintComponent, paintBorder, and paintChildren. They're called in that order and it's the first that paints the component's background. If you overload that one and leave the other two, you should be fine.

Who is calling paintComponent?

For some reason, my paintComponent(Graphics g) method is being called infinitely. I can't seem to tell who is calling it, even if I dump a StackTrace in the call (it's an event that's dispatched and handled).
Are there any easy ways to find out who's triggering the event?
Update: I've found the cause and I now understand the reason. Whoever answers it correctly will get the answer to the question.
Here is the code that's causing the issue:
#Override
public void paintComponent(Graphics g)
{
myJButton.setIcon(ResourceLoader.getImageIconWithLocale(MY_BUTTON_IMAGE));
super.paintComponent(g);
}
FYI: It's a really tricky one!! It's not obvious by looking at the code. I made an assumption that was wrong.
I don't know which component this is, but setting an icon on a button from within a paint routine is a bad idea. It will definitely cause the button to be repainted. If the button is a child of your component then setting the button invalidate the component too causing an infinite loop.
Set the icon somewhere else such as where the dialog / window is set up initially.
The setIcon(ImageIcon) will revalidate and repaint itself ONLY if the ImageIcon is another instance.
When working with Locales, most people are use to the ResourceBundle, which returns Strings, which in turn are immutable. Therefore setting the text over and over doesn't matter.
However, in this case, the ResourceLoader (custom class) returned a new instance of an ImageIcon. Sure it was the same Image, but it was another instance. And if you decompile the code, you'll see that setIcon (at least for JButtons), it will repaint and revalidate if newIcon != oldIcon.
The solution was to use a HashMap in the ResourceLoader, this way it saves from loading the images more than once since most of the images are used very frequently (might as well reuse the instances if you can). Turns out that overall this quick adjustment also saved a decent amount of overall memory consumption as an added bonus.
Are you calling repaint() anywhere? Also, when a window becomes visible (uncovered or deminimized) or is resized, the "system" automatically calls the paintComponent() method for all areas of the screen that have to be redrawn.
The problem is that you are setting the icon in the paintComponent() method. You should never set a property in this method.
Swing components are smart enough to repaint themselves whenever a property changes. In this case you have the problem of the component repainting itself because the Icon changes, but you are also rereading the Icon every time the component repaints itself which is also not very efficient.

Getting correct sizing behaviour in a custom Swing component

I'm creating a custom Swing component that inherits from JPanel.
What is the right way to override/implement the various sizing methods (getPreferredSize, setPreferredSize, getMinimumSize etc.) in order to get "good behaviour", particularly with regards to:
Working with different layout managers
Behaving correctly when setPreferredSize() is called
Reacting appropriately when a border is set via setBorder()
Don't inherit from JPanel unless your component is a composite of several subcomponents. In most cases inheriting from JComponent is enough.
As far as resizing goes... override getPreferredSize, getMinimumSize and getMaximumSize methods to get an appropriate behavior in layout managers.
If your component is a composite of subcomponents in most cases preferred size is already defined by combination of your subcomponents so you don't have to override this one.
Although rather annoying: that depends, on the layoutmanager in this case. Usually the layoutmanager can best be used along with constaints to get a good layout.
I've used GridBagLayout, and after getting used to it, I found it worked pretty well using right GridBagConstraint for each component.
Sometimes a good visual ui designer can help too, like the one from Netbeans, or you could consider a paid one like Swing Designer or JFormDesigner. Can save you some time fiddling with pixels.

Categories

Resources