Java GUI buttons not drawn sometimes (random). Compiz problem - java

*EDIT 2: I just discovered that this is a compiz+java GUI problem. It apparently happens where those two elements intersect.
I'm running the latest Ubuntu 11.04 (classic desktop, not Unity) with all updates. The problem happens with both Sun java and OpenJDK. It is related to using the Window-Rules Compiz plugin -- which I need to use.
As stated in comments below, I previously verified that my controls are added to the correct thread. Now I found that disabling the Compiz Window-Rules plugin resolves my issue. Since I need to use the plugin, I am looking for a solution.*
Original post: I am working on a Java swing application. It was built with NetBeans 6.9. It uses GridBagLayout manager. The look and feel is currently Nimbus (but that doesn't seem to have any effect on the issue I'm going to describe). Most users run the app on Linux. A few use Windows. Most of the time the app works fine. But at random times a view will open without some of the GUI buttons. For example, the Save and Cancel buttons might be missing. The other GUI elements will usually be present (although once I have heard that a view was completely empty with no GUI elements -- just an empty gray window).
If the user closes that view with the "X" in the upper corner and simply re-opens it, it will be drawn correctly. The missing buttons issue happens less than 1% of the time. The close/reopen sequence fixes it almost 100% of the time. (A second close/reopen may have been needed once, if I recall correctly.)
Typically, if some buttons are missing, the other elements are still drawn correctly. This does not affect the whole view (form). It seems to affect the lowermost panel, but I'm not sure if that is actually a repeatable pattern. It is very difficult to reproduce this. I use the software every day and I see this less than once a month. A few users see it more frequently, but it is still rare.
There are no error messages. I have no idea what to try next. This behavior has persisted across different computers, different Linux distros (although all are based on Debian), and many different code changes, including changing the layout manager. (We used the NetBeans GUI designer previously.) Any ideas?
EDIT: 2011.07.05
This is what the code looks like in general:
public void show_some_view() {
setTitle(...)
setLayout(new GridBagLayout());
JPanel butnPanel = new JPanel();
butnPanel.setLayout(new GridBagLayout());
try {
//add stuff to panels (butnPanel, etc.)
} catch (Exception e) {
Logger.log(e);
}
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
int[] wh = ApplicationContext.get().getDisplayWidthxHeight();
setSize(wh[0], wh[1]);
setFocusable(true);
setVisible(true);
}

But at random times a view will open without some of the GUI buttons.
Make sure you add the buttons to the GUI on the EDT. Read the section from the Swing tutorial on Concurrency for more information.
Make sure you add the buttons to the GUI BEFORE invoking setVisible(true);

I had the same problem: sometimes my JMenu wouldn't draw (also on Ubuntu 11.04).
I fixed it by just adding
menuBar.setVisible(false);
menuBar.setVisible(true);
To my code, right after I added it to my JFrame (Which was alreasy set to visible).
I know it's messy but it solved my problem so I'm fine with it.
Hope this helps!

Related

Is displaying a new JFrame a good pratice? [duplicate]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I'm developing an application which displays images, and plays sounds from a database. I'm trying to decide whether or not to use a separate JFrame to add images to the database from the GUI.
I'm just wondering whether it is good practice to use multiple JFrame windows?
I'm just wondering whether it is good practice to use multiple JFrames?
Bad (bad, bad) practice.
User unfriendly: The user sees multiple icons in their task bar when expecting to see only one. Plus the side effects of the coding problems..
A nightmare to code and maintain:
A modal dialog offers the easy opportunity to focus attention on the content of that dialog - choose/fix/cancel this, then proceed. Multiple frames do not.
A dialog (or floating tool-bar) with a parent will come to front when the parent is clicked on - you'd have to implement that in frames if that was the desired behavior.
There are any number of ways of displaying many elements in one GUI, e.g.:
CardLayout (short demo.). Good for:
Showing wizard like dialogs.
Displaying list, tree etc. selections for items that have an associated component.
Flipping between no component and visible component.
JInternalFrame/JDesktopPane typically used for an MDI.
JTabbedPane for groups of components.
JSplitPane A way to display two components of which the importance between one or the other (the size) varies according to what the user is doing.
JLayeredPane far many well ..layered components.
JToolBar typically contains groups of actions or controls. Can be dragged around the GUI, or off it entirely according to user need. As mentioned above, will minimize/restore according to the parent doing so.
As items in a JList (simple example below).
As nodes in a JTree.
Nested layouts.
But if those strategies do not work for a particular use-case, try the following. Establish a single main JFrame, then have JDialog or JOptionPane instances appear for the rest of the free-floating elements, using the frame as the parent for the dialogs.
Many images
In this case where the multiple elements are images, it would be better to use either of the following instead:
A single JLabel (centered in a scroll pane) to display whichever image the user is interested in at that moment. As seen in ImageViewer.
A single row JList. As seen in this answer. The 'single row' part of that only works if they are all the same dimensions. Alternately, if you are prepared to scale the images on the fly, and they are all the same aspect ratio (e.g. 4:3 or 16:9).
The multiple JFrame approach has been something I've implemented since I began programming Swing apps. For the most part, I did it in the beginning because I didn't know any better. However, as I matured in my experience and knowledge as a developer and as began to read and absorb the opinions of so many more experienced Java devs online, I made an attempt to shift away from the multiple JFrame approach (both in current projects and future projects) only to be met with... get this... resistance from my clients! As I began implementing modal dialogs to control "child" windows and JInternalFrames for separate components, my clients began to complain! I was quite surprised, as I was doing what I thought was best-practice! But, as they say, "A happy wife is a happy life." Same goes for your clients. Of course, I am a contractor so my end-users have direct access to me, the developer, which is obviously not a common scenario.
So, I'm going to explain the benefits of the multiple JFrame approach, as well as myth-bust some of the cons that others have presented.
Ultimate flexibility in layout - By allowing separate JFrames, you give your end-user the ability to spread out and control what's on his/her screen. The concept feels "open" and non-constricting. You lose this when you go towards one big JFrame and a bunch of JInternalFrames.
Works well for very modularized applications - In my case, most of my applications have 3 - 5 big "modules" that really have nothing to do with each other whatsoever. For instance, one module might be a sales dashboard and one might be an accounting dashboard. They don't talk to each other or anything. However, the executive might want to open both and them being separate frames on the taskbar makes his life easier.
Makes it easy for end-users to reference outside material - Once, I had this situation: My app had a "data viewer," from which you could click "Add New" and it would open a data entry screen. Initially, both were JFrames. However, I wanted the data entry screen to be a JDialog whose parent was the data viewer. I made the change, and immediately I received a call from an end-user who relied heavily on the fact that he could minimize or close the viewer and keep the editor open while he referenced another part of the program (or a website, I don't remember). He's not on a multi-monitor, so he needed the entry dialog to be first and something else to be second, with the data viewer completely hidden. This was impossible with a JDialog and certainly would've been impossible with a JInternalFrame as well. I begrudgingly changed it back to being separate JFrames for his sanity, but it taught me an important lesson.
Myth: Hard to code - This is not true in my experience. I don't see why it would be any easier to create a JInternalFrame than a JFrame. In fact, in my experience, JInternalFrames offer much less flexibility. I have developed a systematic way of handling the opening & closing of JFrames in my apps that really works well. I control the frame almost completely from within the frame's code itself; the creation of the new frame, SwingWorkers that control the retrieval of data on background threads and the GUI code on EDT, restoring/bringing to front the frame if the user tries to open it twice, etc. All you need to open my JFrames is call a public static method open() and the open method, combined with a windowClosing() event handles the rest (is the frame already open? is it not open, but loading? etc.) I made this approach a template so it's not difficult to implement for each frame.
Myth/Unproven: Resource Heavy - I'd like to see some facts behind this speculative statement. Although, perhaps, you could say a JFrame needs more space than a JInternalFrame, even if you open up 100 JFrames, how many more resources would you really be consuming? If your concern is memory leaks because of resources: calling dispose() frees all resources used by the frame for garbage collection (and, again I say, a JInternalFrame should invoke exactly the same concern).
I've written a lot and I feel like I could write more. Anyways, I hope I don't get down-voted simply because it's an unpopular opinion. The question is clearly a valuable one and I hope I've provided a valuable answer, even if it isn't the common opinion.
A great example of multiple frames/single document per frame (SDI) vs single frame/multiple documents per frame (MDI) is Microsoft Excel. Some of MDI benefits:
it is possible to have a few windows in non rectangular shape - so they don't hide desktop or other window from another process (e.g. web browser)
it is possible to open a window from another process over one Excel window while writing in second Excel window - with MDI, trying to write in one of internal windows will give focus to the entire Excel window, hence hiding window from another process
it is possible to have different documents on different screens, which is especially useful when screens do not have the same resolution
SDI (Single-Document Interface, i.e., every window can only have a single document):
MDI (Multiple-Document Interface, i.e., every window can have multiple documents):
I'd like to counter the "not user friendly" argument with an example that I have just been involved with.
In our application we have a main window where the users run various 'programs' as separate tabs. As much as possible we have tried to keep our application to this single window.
One of the 'programs' they run presents a list of reports that have been generated by the system, and the user can click on an icon on each line to pop open a report viewer dialog. This viewer is showing the equivalent of the portrait/landscape A4 page(s) of the report, so the users like this window to be quite big, almost filling their screens.
A few months ago we started getting requests from our customers to make these report viewer windows modeless, so that they could have multiple reports open at the same time.
For some time I resisted this request as I did not think this was a good solution. However, my mind was changed when I found out how the users were getting around this 'deficiency' of our system.
They were opening a viewer, using the 'Save As' facility to save the report as a PDF to a specific directory, using Acrobat Reader to open the PDF file, and then they would do the same with the next report. They would have multiple Acrobat Readers running with the various report outputs that they wanted to look at.
So I relented and made the viewer modeless. This means that each viewer has a task-bar icon.
When the latest version was released to them last week, the overwhelming response from them is that they LOVE it. It's been one of our most popular recent enhancements to the system.
So you go ahead and tell your users that what they want is bad, but ultimately it won't do you any favours.
SOME NOTES:
It seems to be best practice to use JDialog's for these modeless windows
Use the constructors that use the new ModalityType rather than the boolean modal argument. This is what gives these dialogs the task-bar icon.
For modeless dialogs, pass a null parent to the constructor, but locate them relative to their 'parent' window.
Version 6 of Java on Windows has a bug which means that your main window can become 'always on top' without you telling it. Upgrade to version 7 to fix this
Make an jInternalFrame into main frame and make it invisible. Then you can use it for further events.
jInternalFrame.setSize(300,150);
jInternalFrame.setVisible(true);
It's been a while since the last time i touch swing but in general is a bad practice to do this. Some of the main disadvantages that comes to mind:
It's more expensive: you will have to allocate way more resources to draw a JFrame that other kind of window container, such as Dialog or JInternalFrame.
Not user friendly: It is not easy to navigate into a bunch of JFrame stuck together, it will look like your application is a set of applications inconsistent and poorly design.
It's easy to use JInternalFrame This is kind of retorical, now it's way easier and other people smarter ( or with more spare time) than us have already think through the Desktop and JInternalFrame pattern, so I would recommend to use it.
Bad practice definitely. One reason is that it is not very 'user-friendly' for the fact that every JFrame shows a new taskbar icon. Controlling multiple JFrames will have you ripping your hair out.
Personally, I would use ONE JFrame for your kind of application. Methods of displaying multiple things is up to you, there are many. Canvases, JInternalFrame, CardLayout, even JPanels possibly.
Multiple JFrame objects = Pain, trouble, and problems.
I think using multiple Jframes is not a good idea.
Instead we can use JPanels more than one or more JPanel in the same JFrame.
Also we can switch between this JPanels. So it gives us freedom to display more than on thing in the JFrame.
For each JPanel we can design different things and all this JPanel can be displayed on the single JFrameone at a time.
To switch between this JPanels use JMenuBar with JMenuItems for each JPanelor 'JButtonfor eachJPanel`.
More than one JFrame is not a good practice, but there is nothing wrong if we want more than one JFrame.
But its better to change one JFrame for our different needs rather than having multiple JFrames.
If the frames are going to be the same size, why not create the frame and pass the frame then as a reference to it instead.
When you have passed the frame you can then decide how to populate it. It would be like having a method for calculating the average of a set of figures. Would you create the method over and over again?
It is not a good practice but even though you wish to use it you can use the singleton pattern as its good. I have used the singleton patterns in most of my project its good.

Floating button is AWT?

So, I've always avoided using GUIs in java because, personally, I can't stand GUIs. But, I've started a project which requires me to use GUIs, and, unsurprisingly, I'm having problems.. I have this bit of code..
public class DefaultWindow extends Window
{
private DefaultWindow(Frame owner)
{
super(owner);
contained = owner;
}
public DefaultWindow()
{
this(new Frame(""));
contained.setBackground(Color.black);
contained.setLocation(0, 0);
contained.setSize(1280,720);
Button comp = new Button("Hello");
comp.setLocation(0, 0);
comp.setSize(10, 10);
add(comp);
pack();
contained.setVisible(true);
}
}
.. and it creates a 1280x720 window with a black background (which is good) and it also creates a floating button in the top left-hand corner of my screen.. How do I make the button be in the window?
You're creating an instance of a subclass of Window which, in its constructor, create a Frame (which is itself a Window). You're showing this empty frame, and add the button to the window you're creating. So in the end you have two windows.
I think that what you really want is to create one and only one Frame. Your class shouldn't extend Window, and all this shouldn't be done in a constructor. Moreover, AWT is kind of obsolete. You should be using Swing. Oracle has a great tutorial about Swing, which BTW also explains how to use layout managers (which you should do). Read this tutorial.
Personally, i would use Swing based components over AWT (personally), apart from anything else, there are more components and support.
contained is an invalid reference, you don't need it. You create two windows and only show the one without the button. Drop the reference to the Frame and rely on the window instead
public DefaultWindow()
{
setBackground(Color.black);
setLocation(0, 0);
setSize(1280,720);
Button comp = new Button("Hello");
setLocation(0, 0);
comp.setSize(10, 10);
add(comp);
pack();
setVisible(true);
}
I would avoid setting windows to arbitrary sizes, not all screens are the same.
You will also run foul of the layout manager, meaning that the settings you supply to the button may be overridden.
I would take the time to read through Creating a GUI With JFC/Swing
Q: So, I've always avoided using GUIs in java because, personally, I
can't stand GUIs.
A: Hey: I thought I was alone on the planet :) My motto has always been "GUIs make simple tasks easier ... and difficult tasks utterly impossible" ;)
As far as your question: the answer is:
1) Swing is good for "thick clients" (i.e. Java desktop applications)
2) JSP is good for "web applications) (i.e. client/server web apps)
3) Don't even think about using AWT for your entire GUI. It was deprecated very early in Java history (Java 1.2, specifically).
Here are some good tutorials:
http://www.java2s.com/Code/Java/Swing-JFC/HelloWorldSwing.htm
http://www.ibm.com/developerworks/java/tutorials/j-tomcat/
PS:
Despite what I said about GUIs ... and IDE can be very helpful.
Personally, I use Eclipse. For several reasons:
Eclipse (like most IDEs) can be used for cmd-line, Swing, JSP and Java EE apps.
Eclipse (unlike Netbeans or IntelliJ) is equally useful for Android apps
Eclipse has an extremely broad ecosystem of 3rd party plugins (from companies as diverse as IBM and Google).
IMHO...

How to make the desktop pane that Netbeans has

So when I start up Netbeans, they create a little panel on the desktop for showing the progress of loading. I'm pretty sure Microsoft Office 2010 uses this too. I was curious how to make one of those in java?
I looked through the API and saw JDesktopPane. But I don't think that's what I'm looking for unless you can take that and put in on the actual desktop, but I'm unsure. Thanks in advance!
you can actually do it using JPanel.. you don't need to do anything else..no need of desktop pane
all you need to do is design a JPanel and put a progress bar inside it that will link to a process and show how much it has been completed.
JPanel doesn't have normal frame functionality like minimize, Close etc and will act exactly as you are trying to make up.
Update : Just tried doing what you wanted.
You need to start working on JFrame. and set its decoration to false.
in Netbeans, you can just go to Frame properties and set Undecorated to true
or inside code you can just write setUndecorated(true);
then you have to design your frame, put a progress bar inside it, link it to a function, set its onTop value to true (which means it will always be on top) and set its position to center of screen. done!! you are ready with your window!!

Weird points and lines appearing in custom JPanel when another component updates

so I have been working on developing a GUI for an upcoming project,
and I have to admit that even after about 2 years of Java, I'm still not good at GUI design and programming.
First of all, here's a screenshot of the current version of the JFrame:
I made a little custom JPanel that is going to display a graph later on,
for now it's just random. It's the thing in the lower right. Now if I just repainted that and did all my stuff, nothing would be wrong, but I have to update the JTextArea (which is included in a JScrollPane by the way), I every time set the caret to the very last position, so that it automatically scrolls down. And this causes, in my own custom JPanel, small dots and lines to appear and flicker, which I believe is caused by the JTextArea.
When the window has certain proportions, or if I don't update the caret position, this doesn't occur.
I have already tried a few things: Synchronizing everything related with the EDT, scheduling my repaints, etc. but nothings seems to help.
Has anyone ever come across a similar situation and knows how to fix it?
I could really use some help here.
Thanks in advance,
Tom S.
I think is too hard to say something wise in conections with #camickr's Text Area Scrolling

How do I dynamically add Panels to other panels at runtime in Java?

I'm trying to get into java again (it's been a few years). I never really did any GUI coding in java. I've been using Netbeans to get started with this.
When using winforms in C# at work I use a usercontrols to build parts of my UI and add them to forms dynamically.
I've been trying to use JPanels like usercontrols in C#. I created a JPanel form called BlurbEditor. This has a few simple controls on it. I am trying to add it to another panel at run time on a button event.
Here is the code that I thought would work:
mainPanel.add(new BlurbEditor());
mainPanel.revalidate();
//I've also tried all possible combinations of these too
//mainPanel.repaint();
//mainPanel.validate();
This unfortunately is not working. What am I doing wrong?
I figured it out. The comments under the accepted answer here explain it:
Dynamically added JTable not displaying
Basically I just added the following before the mainPanel.add()
mainPanel.setLayout(new java.awt.BorderLayout());
Swing/AWT components generally have to have a layout before you add things to them - otherwise the UI won't know where to place the subcomponents.
BFreeman has suggested BorderLayout which is one of the easiest ones to use and allows you to 'glue' things to the top, bottom, left, right or center of the parent.
There are others such as FlowLayout which is like a textarea - it adds components left-to-right at the top of the parent and wraps onto a new row when it gets to the end.
The GridBagLayout which has always been notorious for being impossible to figure out, but does give you nearly all the control you would need. A bit like those HTML tables we used to see with bizarre combinations of rowspan, colspan, width and height attributes - which never seemed to look quite how you wanted them.
I was dealing with similar issue, I wanted to change the panel contained in a panel on runtime
After some testing, retesting and a lot of failing my pseudo-algorithm is this:
parentPanel : contains the panel we want to remove
childPanel : panel we want to switch
parentPanelLayout : the layout of parentPanel
editParentLayout() : builds parentPanel with different childPanel and NEW parentPanelLayout every time
parentPanel.remove(childPanel);
editParentLayout();
parentPanel.revalidate();
parentPanel.repaint();
As with all swing code, don't forget to call any gui update within event dispatch thread. See this for why you must do updates like this
// Do long running calculations and other stuff outside the event dispatch thread
while (! finished )
calculate();
SwingUtilities.invokeLater(new Runnable(){
public void run() {
// update gui here
}
}
mainPanel.add(new BlurbEditor());
mainPanel.validate();
mainPanel.repaint();
Try mainPanel.invalidate() and then if necessary, mainPanel.validate(). It also might be worth checking that you're doing this all in the event dispatch thread, otherwise your results will be spotty and (generally) non-deterministic.

Categories

Resources