LWJGL Display.setWidth/Height? - java

Similar to what you can do with a Java's Canvas class, I am currently trying to write a method to set an LWJGL Display's maximum size. The only problem I have run into is that LWJGL's Display class doesn't have a setWidth or setHeight method, and I can't think of an way I could write my own. My first thought was to somehow get the instance of the JFrame that the window was using, but there's no method for this either so I feel like I am SOL. I also tried using DisplayMode and just resetting the size through that, but it closes the window and reopens it every time it resizes. I am trying to write a method that'd simply resize the window as if the user was dragging it to enlarge it. Does anybody know how I could/should go about doing this? Is it even possible to get this smooth max-size effect I am looking for, considering that the display doesn't even update until you let go after dragging/resizing it manually?

If you need more control over your window, you can try using an AWT Frame as a parent to an LWJGL Canvas. This would allow your code to take advantage of default window methods, including setWidth() and setHeight() found in the Java standard libraries, prevent and control window behavior, and add listeners to run code for certain events.
First, import java.awt.* and then set up code that looks something like this:
Create a Frame and Canvas:
Frame frame = new Frame("LWJGL Game Window");
frame.setLayout(new BorderLayout());
Canvas canvas = new Canvas();
Add the Canvas to the Frame:
frame.add(canvas, BorderLayout.CENTER);
Setup LWJGL and apply it to the Canvas:
try {
Display.setParent(canvas);
frame.setPreferredSize(new Dimension(1024, 786));
frame.setMinimumSize(new Dimension(800, 600));
frame.pack();
frame.setVisible(true);
Display.create();
while(!Display.isCloseRequested() && !closeRequested)
{
// main code or call to code goes here
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
Display.update();
}
Display.destroy();
frame.dispose();
System.exit(0);
} catch (LWJGLException e) {
e.printStackTrace();
}
Not sure how much you know about Java, but from here, you could add an ActionListerner or ComponentListerner that does something if the window is resized.
Also check out the LWJGL wiki for AWT Frames. This should, at least, help to point you in the right direction.

Related

Java Swing elements change every runtime

So I made a program using java's swing library. I made a program that graphs equations and here is the main method if it's relevant:
public static void main(String[] args) throws Exception {
JFrame frame= new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setLayout(new GridLayout(1,2));
GraphPanel gp = new GraphPanel();
GraphPanel gp2 = new GraphPanel();
//gp.functs.add(new Function(Phrase.createPhrase("2(25-x^2)^(1/2)")));
//gp.functs.add(new Function(Phrase.createPhrase("-1.1((25-x^2)^(1/2))")));
gp.functs.add(new Function(Phrase.createPhrase("x^2")));
//gp.functs.add(new Function(Phrase.createPhrase("-4/x^2+6")));
gp2.functs.add(new Function(Phrase.createPhrase("sinx")));
frame.add(gp);
frame.add(gp2);
frame.pack();
frame.setSize(800, 800);
//gp.setBorder(BorderFactory.createLineBorder(Color.RED));
gp.setBounds(100, 100, 700, 700);//I WANT THIS TO ALWAYS RUN
}
I ran two trial runs of the program WITHOUT CHANGING ANY PART OF IT and this is what it looked like:
Then the next time i ran it:
If it's relevant, GraphPanel is of type JLabel.
I know that if i use a null absolute LayoutManager, it will always work. But I'm just wondering why swing has such inconsistencies in it. I've noticed stuff like this before but I though it was just some error in the program. Why is this?
Thanks in advance!
Start by moving frame.setVisible(true); to the end of the main method
This gp.setBounds(100, 100, 700, 700); is pointless, as gp is under the control of a layout manager (GridLayout)
There's no point in using both path and setSize, pack is generally a safer option, but that will depend on your components correctly overriding getPreferredSize
But I'm just wondering why swing has such inconsistencies in it. I've noticed stuff like this before but I though it was just some error in the program. Why is this?
Mostly because you're not using the API properly. It's possible, because of the way a JFrame is physically attached to a native peer, that the frame may or may not actually be visible on the screen when you reach gp.setBounds.
Also, because you're doing all your work from within the "main" thread and not the Event Dispatching Thread, you're running the risk of a race condition between them, see Initial Threads for more details.
Swing is VERY flexible, it's also unforgiving when you do the wrong things (or things the wrong way)

A transparent JFrame that is always on top, but allows clicking underneath

So, i'm making a program that currently just accepts a file that'd been dragged and dropped into it. I'm using a JFrame for the container at the moment, but I dont think that's really important.
I want the window to always be on top when running, so that if you drag any file to the bottom right corner of the screen, the program will handle it. But, at the same time, i want the program to be able to be invisible, and click-through-able, meaning that you can click on anything underneath the jframe, while it's invisible, but still be able to drag a file into the program without having to do anything special.
I've never heard of something like this, but I'm sure it must be possible. How would I do this?
I made a Splash screen the other day that was click-through-able. You might want to make a completely transparent image using Photoshop or something else. Here is the code:
private BufferedImage splash;
/**
* Create the frame.
*/
public Splash() {
this.setUndecorated(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(500, 500);
setLocationRelativeTo(null);
try {
splash = ImageIO.read(getClass().getResource("/images/transparent.png"));
} catch (Exception e) {
e.printStackTrace();
}
// Apply a transparent color to the background
// This is REALLY important, without this, it won't work!
setBackground(new Color(0, 255, 0, 0));
getContentPane().setBackground(Color.BLACK);
add(new JLabel(new ImageIcon(splash)));
setVisible(true);
}

Paint hidden Java swing component

I've tried to paint component to PDF. I've got itextpdf 4.2 and everything works perfectly.
But this works only if I make visible the frame that I've tried to render.
The similar question that I've found is How to paint an invisible JFrame elsewhere? that has the same issue, but the solution wasn't provided in answer.
A little of code.
I've created a JFrame and insert main view that I want to render.
JFrame jframe = new ShowingFrame();
jframe.setPreferredSize(new Dimension(PDFHelper.getOriginalWidth().intValue(), PDFHelper.getOriginalHeight().intValue()));
jframe.setMinimumSize(new Dimension(PDFHelper.getOriginalWidth().intValue(), PDFHelper.getOriginalHeight().intValue()));
jframe.add(view);
jframe.setUndecorated(true);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setState(Frame.ICONIFIED);
jframe.setState(Frame.NORMAL);
//jframe.setVisible(true);
If I uncomment jframe.setVisible(true) than everything works.
But user will see this frame that I want to avoid.
So the question is: How to paint hidden control?
Inside Swing Component.java class all paint methods first check if the component is visible:
public void paint(Graphics g) {
if (isShowing()) {
// rest of the code...
}
}
I've tried to create inherit class ShowingFrame extends JFrame, that override isShowing and always return true. But this not helps to.
Swing (and the Java Graphics API) is optimized to stop rendering as soon as possible.
So the solution is to create a BufferedImage, get the Graphics instance from it and then call component.paint(g); with it.
Now you have a tab component. Try to get the content of the tab instead of rendering the tab itself. If that doesn't work, you can try to clone the tree of children, create a new JPanel, attach the children and render the result. But cloning can become tedious if the models don't behave well.
See this question for some code: Swing: Obtain Image of JFrame
Why do you want to paint something that is not visible? Your computer does not want to waste CPU cycles rendering graphics that can't be seen. In fact, there is a lot of computations done to see what parts of each window are visible and only paint the visible parts (the so called clip window).
If you want to paint something so you can use it later or save it you can always create a BufferedImage of the size you want and paint to that.
If I uncomment jframe.setVisible(true) than everything works. But user will see this frame that I want to avoid.
You can set the frame location so that it is not visible on the screen. Maybe something like:
frame.pack();
Dimension d = frame.getSize();
frame.setLocation(-d.witdh, 0);

JFrame.setResizable(false); not working

I'm working on an online mode for a new game and in order to prevent cheating I need fix window sizes (and both players need a window with the same sizes).
I used 'jframe.setResizable(false);' but it seems to be "glitchy".
When I click the window and move it away from the border of the screen, Windows does minimize it.
Here's a video about it:
http://www.youtube.com/watch?v=AQ7OHJOuLSk&feature=youtu.be
I've tried following code in order to fix it:
Dimension d = new Dimension(width, height);
panel.getJFrame().setMaximumSize(d);
panel.getJFrame().setMinimumSize(d);
panel.setMaximumSize(d);
panel.setMinimumSize(d);
and I created a Component Listener:
if (max_height!=-1){
if (e.getComponent().getSize().getHeight()>max_height){
e.getComponent().setSize((int) e.getComponent().getSize().getWidth(),max_height);
}
}
if (max_width!=-1){
if (e.getComponent().getSize().getHeight()>max_width){
e.getComponent().setSize(max_width,(int) e.getComponent().getSize().getHeight());
}
and I tried to work with Layouts but nothing worked.
What I need now is either the possibility to prevent that minimize "glitch" (If it is a glitch) or a way to make the JPanel not resizable. Like when the size of the JFrame window is changed, the JPanel always stays the same. It's neither streched nor minimized.
Help is much appreciated :)
Sincerely Felix
So far the best patch for this annoying issue is the following. Doesn't matter where you call the setResizable(false) method. Just add this piece of code after you setVisible(true).
private void sizeBugPatch() {
while (frame.getWidth() > yourWidth) {
frame.pack();
}
}
Where yourWidth is the width you've set in any of the possible ways, either manually or by overriding setPreferredSize methods. The explanation is quite easy, frame.pack() seems to reset frame.setResizable(boolean b) somehow. You could use an if instead of the while loop but I prefer while to exclude the case the window would still be extra-sized even after a second pack().
Did you initialize the variable jframe or are you calling the general Class?
Because if you do it like this:
JFrame frame = new JFrame();
frame.setResizable(false);
It works fine for me...

JToolbar doesn't show on Ubuntu if set to BasicToolBarUI

I've decided to have my own custom UI of JToolBar by
subclassing BasicToolBarUI, as part of my Swing program.
It works great under OS X (10.6) and Windows (7), but
when it comes to Linux, problem occurs:
If the swing component is
Using SystemLookAndFeel (With Java LAF it is shown)
Using UI BasicToolBarUI (To simplify the problem. With this it already doesn't work)
running under Linux (Ubuntu 10.10)
the whole JToolBar doesn't appear anymore.
Can anyone give a hand on this? How to make it appear again on Linux? Thank you in advance.
(I've done the custom UI in order to
let user still able to move the toolbar to other edges
of the window, but prevent it from going to floating state.)
Cheers,
Shuo
My SSCCE:
// Set the system look and feel:
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
// Create frame
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(200, 100));
// Create toolbar
JToolBar toolbar = new JToolBar(JToolBar.HORIZONTAL);
toolbar.add(new JButton("Foo"));
// With this line toolbar doesn't appear any more (only) on Linux.
toolbar.setUI(new BasicToolBarUI());
// Show UI
panel.add(toolbar);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
You may not see it because you haven't added anything to it (actions, buttons etc). Empty toolbar usually has height of 1-2 pixels.
UPDATE:
From what I can tell by looking at BasicToolBarUI it doesn't really do anything - you have to implement size calculations and painting yourself to get proper results

Categories