Metal LAF JScrollPane rendering bug? - java

Having played around with the JScrollPane class for a couple of days, I've come across a very strange rendering problem regarding the horizontal JScrollBar compnent. When using these components within the default swing "Metal" look-and-feel, the center gripper pattern of the horizontal scrollbar appears to render incorrectly at specific content/viewport dimensions.
The code below opens a simple JFrame window with an embedded JScrollPane component, which appears to exhibit strange rendering behaviour as the horizontal scrollbar is dragged towards its rightmost extemity. As the rendering of the horizontal scrollbar gripper appears to be dependent upon the size of the content/viewport, this code opens the parent JFrame with an explicit dimension of 1402x800. Varying dimensions appear to have the same effect, including a maximized window at a 1440x900 resolution, and the problem tends to present itself more readily in a non-composited desktop environment (i.e. Windows XP or Vista/7 running a basic/classic theme).
public class Main
{
public static void main(String[] args)
{
ScrollbarTest application = new ScrollbarTest();
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
public class ScrollbarTest extends JFrame
{
public ScrollbarTest()
{
super("Scrollbar Test");
Container container = getContentPane();
JScrollPane scrollPane =
new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
JPanel contentPanel = new JPanel();
contentPanel.setPreferredSize(new Dimension(8000, 8000));
scrollPane.getViewport().add(contentPanel);
container.add(scrollPane);
setSize(1402,800);
setVisible(true);
}
}
As I am prohibited from uploading images directly to this forum, I have placed an image here depicting the anomaly that I'm currently experiencing. As you can see, the center gripper feature is not rendered correctly as I drag the horizontal scrollbar toward its right extremity. Please note that this does not appear to happen at all window sizes, but the initial JFrame dimension of 1402x800 certainly does the trick on my system. To be perfectly honest, this problem was not apparent until I moved from a 1280x800 to 1440x900 screen.
Any comments regarding the reproducibility and/or cause of this anomaly would be gratefully received.
Best regards, Lee.

Thank you all for taking the time to read this post. As we are not professional programmers, we had to seek advice in order to ensure that we were using the java API correctly.
We asked the guys at Sun to take a look at our problem, and this does appear to be a bug with the swing "Metal" look-and-feel. Please see below for the relevant correspondence.
Dear Java Developer,
Thank you for reporting this issue.
We have determined that this report is
a new bug and entered the bug into our
internal bug tracking system under Bug
Id: 7017935.
You can monitor this bug on the Java
Bug Database at
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7017935.
It may take a day or two before your
bug shows up in this external
database. If you are a member of the
Sun Developer Network (SDN), there are
two additional options once the bug is
visible.
Voting for the bug Click http://bugs.sun.com/bugdatabase/addVote.do?bug_id=7017935.
Adding the report to your Bug Watch list. You will receive an email
notification when this bug is updated.
Click
"http://bugs.sun.com/bugdatabase/addBugWatch.do?bug_id=7017935".
The Sun Developer Network
(http://developers.sun.com) is a free
service that Sun offers. To join,
visit
"https://softwarereg.sun.com/registration/developer/en_US/new_user".
Regards, Java Developer Support
Best regards, Lee.

Related

Java transparent JPanel (allwaysOnTop) triggers Taskbar

I recently wrote a program in Java, that functions as a game-overlay (in order to create custom gamemodes in games like Rainbow Six: Siege) by applying the following settings:
clientFrame = new JFrame("Window");
clientFrame.setSize(400, 300);
clientFrame.setUndecorated(true);
clientFrame.setBackground(new Color(0,0,0,0));
clientFrame.setAlwaysOnTop(true);
clientPanel = new JPanel();
clientPanel.setOpaque(false);
textArea_Messages = new JTextArea();
textArea_Messages.setEditable(false);
textArea_Messages.setBackground(new Color(0,0,0,0));
textArea_Messages.setFont(font);
clientPanel.add(textArea_Messages);
clientFrame.getContentPane().add(BorderLayout.CENTER, clientPanel);
clientFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
clientFrame.setVisible(true);
clientFrame.pack();
This worked for me the last few months. I had to run the game in borderless window mode in order to display the panel on top of my game, but I was able to Alt+Tab out of the game to change some gamemode settings and reentering it by clicking inside the game window. My JPanel stayed allways on top, and the taskbar disappeared while playing.
Today I noticed that the taskbar doesn't hide anymore. Either it stays on top together with my JPanel, or the JPanel (and the taskbar) aren't visible. I've searched online for hours trying to solve this issue and tested everything (Repinnig every icon, Restarting Explorer.exe, changing the taskbar-preferences...).
However, when checking the "Allways on top" option in the Task-Manager, the taskbar disappears while playing! This leads me to the assumption that the JPanel somehow keeps the taskbar in focus, while the taskmanager doesn't.
Does someone know what causes this issue?
Some more information that might be relevant:
-The game got an update a few days ago
-I was using Classic Shell all the time
-Windows got an update that forced me to reinstall Classic Shell
I know, my problem does not sound that terrible, but I'm recording my custom gamemodes for Youtube and the taskbar is really annoying.
Thanks in advance :)

Can you put JFrames inside Full Screen Exclusive Mode?

To be honest, I didn't quite know how to express my question in the title. So if someone has a clearer idea of what i'm trying to ask, then please be so kind as to edit it, for the greater good of mankind.
I have the following code:
public class Main {
public static void main(String[] args) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
JFrame frame = new JFrame();
Window window = new Window(frame);
JButton btn = new JButton("Quit");
window.add(btn);
if(gd.isFullScreenSupported())
gd.setFullScreenWindow(window);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
gd.setFullScreenWindow(null);
}
});
}
}
What I want to do is make a library system, illustrated in full screen mode. Inside the full screen mode, there should be simple frame windows with text fields in them and so on... No heavy 2D/3D graphics required here...
My problem is, the quit button is resized to fit the entire screen. I've tried to use setBounds, setSize, etc, on the frame, window and even button... But it doesn't seem to let me be able to center the button in the middle.
So my question: Is it possible to make JFrame application windows inside a JFrame application window which is set to full screen exclusive mode? Or is it only possible to use full screen exclusive mode together with 2D/3D methods like drawing?
Note: The only thing I intend to use full screen mode for is to set it to a black background, and have a Jframe window ontop of this black background in the center of the application. It is to give the illusion that the application is actually a system.
Thank you.
P.S. please note that the quit button was merely for my own testing purposes. It won't be part of the actual system, so my question does not revolve around how to resize this particular quit button.
Fullscreen Exclusive Mode is not meant to have Swing components inside. It is meant as a high performance way to draw graphics in Java (and can benefit as much as possible of underlaying hardware if done right).
What you want to do could be done by using an undecorated JDesktopPane and maximize it over the dimensions of the screen. Then proceed with using a JInternalFrame to have a JFrame like window inside that JDesktopPane.
I've included links to the respective API sections, they should get you started.
I think that what you are after is an MDI Application. If that is what you are after you could take a look here.
Your problem is that you do not use layout manager correctly.
Learn about layout managers - the modules that put and size/resize the visual components on screen. Then decide how do you want your button to look like and then decide which layout manager to use. It will do its job.
You know what i also had the exact same problem and the only thing i know from my experience is that you can use jinternal frame and set its property undecorated to true then add your custom title bar according to your requirement.

Netbeans 7.0.1 acts weird, couldn't even edit the GUI in design mode

I'm experiencing a very weird problem in Netbeans 7.0.1 while designing a GUI.
At first it was all good, I could design and adjust all the swing components easily and normally. But today, for any reason, it turned to be faulty in which the whole JFrame is extended vertically way way way down (~37,000 in height!), and all the components mixed up messily. However, I couldn't do anything about this, since this happened it doesn't allow me to drag the frame's bottom side upward to minimize the height.
The worst thing is that I couldn't select (click on) some of the components, but some others can be. I don't know how to thoroughly explain this weird thing, just have a look at the Screen shot.
Tell me if you need any further info.
Cheers.
Select the JFrame component from the Navigator panel, and change the height of the JFrame from the properties panel to something like 200. Once you get the size under control, you can use mouse for resizing it to desired size.
This condition may happen if something went wrong while closing the file or if the IDE was terminated abruptly and if the IDE does not get a chance to write all the metadata about the UI properly.
First Note that You can't resize the JFrame if one of the components is the same length as th JFrame. Try resizing that tabbed pane first, then also the list on the left of the tabbed pane (Ongoing Projects).
Next use the inspector to select any component you couldn't select. It might be that another transparent component is covering it, or that it is in a panel and the panel is getting selected instead. Or even the other way round when you can't select a panel because it contains another component. So use the inspector to select components instead.
Finally, if the scroll bar is too long for you to resize easily, you can use the properties window, but note like I said, resize the components in the JFrame first before resizing the JFrame.
Hope this helps
Try to change the size (Height and width) of frame in preferredSize property,and use Panels. Without panels you cannot achieve the arrangement of different objects on a Frame.
After a lot of frustration over multiple failed attempts at fixing this issue using all the tips given by the users above [thanks everyone, but it didn't work :( ], I restarted the NetBeans application in despair. It worked. Hopefully this'll help someone else with the same problem!

JScrollPane doesn't show if BorderLayout constraint is CENTER?

Been developing a game for a while, and currently re working the GUI, or at least trying to. Had the massive problem of not being able to resize the frame (without issues), as I didn't understand layout managers very well. A few projects later, and time to come back and do some more on the game, and I hit a problem...
The basic layout of the main frame is, mainPane, containing one gameScrollPane and one controlPanel. The scroll pane is a scroll pane, and the control panel a normal panel. The scroll pane contains the main game panel.
As I wanted the scroll pane to take up most of the screen, with the control panel taking up a small lower area, much the same as many Sim like games, so chose the Border layout for the mainPane. I added the scroll pane and set the constraints CENTER and the control panel added and constriants SOUTH. This didn't show the scroll pane, so I played around trying different constraints, and it seems that only when I set the scroll pane constraint to North, does it display at all.
To demonstrate this, I have created a quick video...
http://screenjel.ly/q5RjczwZjH8
As you can see, when I change the value of NORTH to CENTER and re run, it's like its not there!
Bonus points for anyone who can see a clear second problem which I may start another question for after this issue is solved!
I thank you for your time to read this.
Thanks in advance for any ideas or thoughts :)
Rel
If you'd posted some code to start with then you might have gotten a really quick answer. Luckily, you posted a link in the comments to the other response.
The setContentPane() stuff is weird, especially after doing some things to it that will then get wiped out. However, that's not your problem.
The issue is that you are adding levelMaker and personMover right to mainPane without any constraints. These will then be blowing away anything you set for CENTER... in this case the previously set gameScrollPane.
That's why you see it for NORTH and not for CENTER.
I can't get the video to show. It's been buffering for ages.
My guess would be that the scrollpane is in fact filling the center; it's just your game panel that's not being shown.
Your game panel needs to return reasonable values for getPreferredSize().
Update
Another thing you may want to do is have your game panel implement the Scrollable interface. You can then override getScrollableTracksViewportWidth and ...height to return true so your panel will be forced to the scrollpane's dimensions.

Resize JScrollPane client without scrollbars rolling

I have a JScrollpane which contains a scrollable client that changes its size dynamically while using the application. I want the JScrollPane to be aware of the changes without moving the viewport when the client size changes.
To clarify what I mean:
Refer to the Java Webstart example ScrollDemo2 from the article How to use scroll panes by Sun. When clicking at the bottom of the window, a circle appears partly outside the window and the scrollbars move. It's the latter behavior I want to avoid.
My guess is that it's just a matter of setting a simple flag in one of the many components that are involved in a scroll pane solution, but I just can't find where it is. Does anyone know?
I managed to solve this problem by overriding the standard behavior of the viewport in my JScrollPane. This might be a solution that is not suitable for all, but in my GUI this works like a charm.
JScrollPane pane = new JScrollPane();
pane.setViewport(
new JViewport(){
/**
* An empty override implementation to prevent undesired scrolling on
* size changes of the client.
*/
#Override
public void scrollRectToVisible(Rectangle rect){}
});
I would try something like:
Point p = scrollPane.getViewport().getViewportPosition();
revalidate();
scrollPane.getViewport().setViewportPosition(p);
You may need to wrap the last line of code in a SwingUtilities.invokeLater.
If that doesn't work then maybe you can disable/enable the viewport before and after the revalidate()?

Categories

Resources