My Window is Forced to Maximized on Java Applet/JFrame - java

I've tried running both an Applet and a JFrame following certain YouTube tutorials, but when they run on my computer, they ignore the size I specify for the window, and forcibly open maximized and will simply not resize.
Here's a simple example Applet I ran:
package pong;
import java.applet.Applet;
import java.awt.*;
public class Pong extends Applet{
final int WIDTH = 700, HEIGHT = 500;
public void init() {
this.resize(WIDTH, HEIGHT);
}
public void paint(Graphics g) {
}
public void update(Graphics g) {
}
}
I cannot resize the window/panel. I don't know if this is an issue with my computer Yoga 2 Pro.
Any help is greatly appreciated.
EDIT: I think perhaps I wasn't clear enough. I am simply not managing to correctly view ANY JPanel or Applet. They display on my Yoga 2 Pro as maximized, and with their content being strange as well. In this example I'm simply trying to get a 700x500 window, but Java ignores this fact on my computer.
Thanks

Related

Graphics 2D not drawing images in Java

I'm following a Java course, and the current idea is to draw an image using Java Graphics2D. I'm following the steps one by one, but it seems not to be drawing anything. The panel is shown within the frame and everything is correct, but the image is not drawn. I'm using Java 15 and the course is Java 13.
JPanel class code:
public class MyPanel extends JPanel implements ActionListener {
Image ball;
int x = 0;
int y = 0;
MyPanel(){
this.setPreferredSize(new Dimension(PANEL_WIDTH,PANEL_HEIGHT));
this.setBackground(Color.BLACK);
ball = new ImageIcon("ball.png").getImage();
}
public void paint(Graphics g){
Graphics2D G2D = (Graphics2D) g;
G2D.drawImage(ball,x,y,null);}
JFrame class code:
public class MyFrame extends JFrame{
MyPanel panel;
MyFrame(){
panel = new MyPanel();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(panel);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
Main class code:
new MyFrame();
I picked out most of the relevant code.
First, I recommend reading through Performing Custom Painting and Painting in AWT and Swing to get a better idea of how painting in Swing should work.
I then suggest reading through Reading/Loading an Image
The "problem" with ImageIcon is that
It doesn't report any errors if the load fails
It loads the image in a second thread, which means you don't know (easily) when it's available
ImageIO on the hand will throw an error if the image can't be loaded, which is much easier to diagnose, and will only return AFTER the image is fully loaded and available.
One concept which can be hard to grasp when your starting is the concept of "embedded" resources. Java allows you to package "resources" along with your code. These resources live within the context of your programs class path and make it MUCH easier to load when compared to having to deal with external files.
Have a look Packaging and accessing run-time resources in a runnable Jar for some basics.
Depending on the IDE you're using, it's usually pretty easy to "copy" these resources into your project/src and allow the IDE to package itself.
The problem with a question like this is it's very, very hard for anyone to truely diagnose, as there are so many reasons why the image might not have loaded and the solution is usual one of trial and error.
Me, I'd start by just drawing some lines/rectangles and make sure that paint is been called. I'd then look at things like the image's size, to make sure it's not something like 0x0.
Runnable example
This is a simple runnable example based on comments I made above. I'm using NetBeans and the image was stored in the "Source Package" (so, along with the other source code) under the /images package
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage beachBall;
public TestPane() {
try {
beachBall = ImageIO.read(getClass().getResource("/images/BeachBall.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (beachBall == null) {
return;
}
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - beachBall.getWidth()) / 2;
int y = (getHeight() - beachBall.getHeight()) / 2;
g2d.drawImage(beachBall, x, y, this);
g2d.dispose();
}
}
}
It really looks like your image is not loaded.
As #MadProgrammer just told, new ImageIcon("ball.png") does not raise any error, and getImage() will always return something (not null), even if the file is not properly loaded.
To make sure your image is available, you can try ball.getWidth(null), and
if it returns -1, then something went wrong.
You can check the root path used by the JVM ("execution" location) with System.getProperty("user.dir"), the image file has to be exactly in this folder.
I tried your code with java 1.8 and it works well.

Resizing JFrame in one dimension

I am trying to re-size my JFrame in only one dimension (width in this case) and I found this question JFrame re-sizable height ONLY which gave me a good answer for doing so;
addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
setSize(new Dimension(preferredWidth, getHeight()));
super.componentResized(e);
}
});
and I edited it slightly so that instead of locking width it locked height to a certain size and allowed width to be re-sizable.
import java.awt.*;
import java.awt.event.*;
import java.awt.Dimension;
import java.awt.Component;
import javax.swing.*;
import java.io.*;
import java.lang.*;
public class mcve
{
JFrame numberConversionWindow = new JFrame("Number Conversion");
public void numberConvertGUI()
{
numberConversionWindow.setBounds(10, 10, 420, 300);
numberConversionWindow.addComponentListener(new ComponentAdapter()
{
#Override
public void componentResized(ComponentEvent e)
{
numberConversionWindow.setSize(new Dimension(numberConversionWindow.getWidth(), 300));
super.componentResized(e);
numberConversionWindow.repaint();
}
});
numberConversionWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
numberConversionWindow.setLayout(new GridLayout(1,1));
numberConversionWindow.setVisible(true);
}
public static void main(String[] args)
{
mcve mc = new mcve();
mc.numberConvertGUI();
}
}
However there is a problem with this code. It often glitches. As I start to re-size it to make it wider there is a black line which flickers just before the frame re-sizes.
The next glitches are caused when re-sizing the height. It may just leave a large black area instead of snapping back to 300, and sometimes it will not snap back at all.
So my question is how can I improve this code to prevent these glitches from happening and instead of just having a height which it will snap back to can I disable the ability to re-size the height? If I can disable this ability, how would I do so?
Edit
I have also tried the following code
numberConversionWindow.setMinimumSize(new Dimension(420, 300));
numberConversionWindow.setMaximumSize(new Dimension(numberConversionWindow.getWidth(), 300));
However this still lets me re-size the height of the JFrame.
Any Help would be greatly appreciated
Edit 2
I have attempted to try and use another answer from JFrame re-sizable height ONLY. My problem for this attempt is a can't find symbol question.
I have the code
public class NumberConverter
{
...
static
{
if (System.getProperty("sun.arch.data.model").equals("32"))
{ // 32-bit JVM
System.loadLibrary("my32bitdll");
System.out.println("Running 32-bit JVM");
}
else
{
// 64-bit JVM
System.loadLibrary("my64bitdll");
System.out.println("Running 64-bit JVM");
}
}
//public static native int getComponentHWND(numberConversionWindow);
//public static native int setMinMaxResizeBoundaries(getComponentHWND, 420, 300, numberConversionWindow.getWidth(), 300);
public void numberConvertGUI()
{
numberConversionWindow.setBounds(10, 10, 420, 300);
int hwndForJFrame = getComponentHWND(numberConversionWindow);
numberConversionWindow.setMinMaxResizeBoundaries(hwndForJFrame, 420, 300, numberConversionWindow.getWidth(), 300);
...
}
public static void main(String[] args)
{
NumberConverter nC = new NumberConverter();
nC.numberConvertGUI();
}
}
When I compile I get the errors cannot find symbol - method setMinMaxResizeBoundaries(int,int,int,int,int) and cannot find symbol - getComponentHWND(numberConversionWindow). I would greatly appreciate someone explaining to me how I am meant to use setMinMaxResizeBoundaries & getComponentHWND properly, and how I am meant to input it in my code. As in wether I am meant to use the public static native int or I am meant to put it in the void numberConvertGUI()
The original answer on JFrame re-sizable height ONLY is
static {
if (System.getProperty("sun.arch.data.model").equals("32"))
{ // 32-bit JVM
System.loadLibrary("my32bitdll");
System.out.println("Running 32-bit JVM");
} else {
// 64-bit JVM
System.loadLibrary("my64bitdll");
System.out.println("Running 64-bit JVM");
}
}
// Sets a window to never be resized above or below these minimum widths/heights
public static native int setMinMaxResizeBoundaries(int hwnd, int minWidth, int minHeight, int maxWidth, int maxHeight);
Extra bit of code
// Returns the HWND for the specified component, or -1 if does not exist
public static native int getComponentHWND(Component c);
The short answer is you can't. In Swing all events go to your Java code, then update the on screen graphics... except for resizing windows. The window itself is a native control. Events go to the window first, then to the Java side. Your original code works on the Java side so the window has already resized by the time you size it back. That's what causes the glitchy behavior.
The only way around this (short of digging into C++ native code) is to disable native window decorations and render your own resize handles. Then your code would receive the resize events before the native window does and the glitches would go away. Not a trivial amount of work, but it might be feasible depending on your use case.

Why do my java graphics lag so much?

I know there are already many questions about slow java graphics, but none of them have solved my problem. The lag in my program seems very unnatrual, and has no explanation as far as I can tell.
I am creating a 2D game, and it has terrible lag. At first I thought it was from all the graphics being drawn in the game, so I did many things to try and improve performance, but none of them changed anything.
To make sure it was the game that was causing lag, I made a very simple (badly written) program that just moves a square across the screen.
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main extends JPanel{
static Main main = new Main();
int x;
int y;
public static void main(String[]args){
JFrame frame = new JFrame("Test");
frame.setSize(1920, 1080);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(main);
frame.setVisible(true);
while(true){
main.update();
main.repaint();
try {
Thread.sleep(1000 / 60);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void update(){
x++;
y++;
}
public void paint(Graphics g){
super.paint(g);
g.fillRect(x, y, 100, 100);
}
}
To my suprise, this simple program lags very badly too! I have been coding the game on linux (ubuntu GNOME 14.10), but I have run it on my Windows 7 partition as well, and it doesn't change the performance. I have also updated all my graphics drivers. My computer can also run other java programs such as Minecraft with no lag at all. I even tried importing the project file for this tutorial into eclipse and running it and it ran fine: https://www.youtube.com/watch?v=ar0hTsb9sxM
Why is this happening, and how can I fix it?
I put Toolkit.getDefaultToolkit().sync(); in my render method which appears to fix it. However you should put a If os is linux before that.

Is there any default java class for a Popup JDialog?

I have been using this code to implement a Popup JDialog of sorts, like what you see when your anti-virus is scanning your system or updates itself:
import java.awt.*;
import javax.swing.JDialog;
import javax.swing.JLabel;
public class PopupDialog extends JDialog {
public PopupDialog() throws HeadlessException {
createUI();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
PopupDialog popupDialog = new PopupDialog();
popupDialog.setVisible(true);
}
});
}
private void createUI() {
setTitle("Popup Dialog");
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
addComponentsToFrame();
//This call will give screens viable area, which takes into account the taskbar, which could be at the bottom, top,left or right of the screen.
Rectangle maxBounds = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
//get screen size
int sWidth = maxBounds.width, sHeight = maxBounds.height;
setSize(275, 225);//set frame size
Dimension appDim = getSize();
//get app size
int aWidth = appDim.width, aHeight = appDim.height;
//set location like a tooltip would be except its a custom dialog like an AV
setLocation(sWidth - aWidth, (sHeight - aHeight));
}
private void addComponentsToFrame() {
JLabel label = new JLabel("Popup Dialog");
getContentPane().add(label, BorderLayout.CENTER);
}
}
But my question is: is there any class or package in java that will do this for me? and if not how would I go about allowing the JDialog to slide up from the taskbar (or offscreen)? or somehow become visible in a slow manner like a ToolTip Popup would from the system tray. Thanks.
EDIT The reason i want to use a JDialog or Frame is because i want to be able to fully skin the Popup window, using setUndecorated(true); and adding custom exit icons, backgrounds etc
You mean like the examples here: http://docs.oracle.com/javase/tutorial/uiswing/misc/systemtray.html ?
First, you can make your frame be always on top, this will ensure it is always visible. Next, you could position the frame off the bottom of the screen and slide it up programmatically. This should be fairly smooth even on an older XP machine. There is no standard Java API to do this but you can do it yourself pretty easily. Another option instead of sliding is to make the window fully transparent and fade it in. This API was added in recent (last 2 years) Java 6 updates, so it should be available everywhere.

Making a Java panel fullscreen

How would you make a JComponent (panel, frame, window, etc.) fullscreen, so that it also overlaps everything on the screen including the windows start bar?
I don't want to change the resolution or anything with the graphics device like bitdepth etc, I just want to overlap everything else.
Check out this tutorial describing Java's Full-Screen mode API.
Example code (taken from the tutorial). Note that the code operates on a Window so you would need to embed your JPanel with a Window (e.g. JFrame) in order to do this.
GraphicsDevice myDevice;
Window myWindow;
try {
myDevice.setFullScreenWindow(myWindow);
...
} finally {
myDevice.setFullScreenWindow(null);
}
You can try some of the codes in this page, allowing a container to fill the screen (so it is not a solution for an individual component, but for a set of components within a container like a JFrame)
public class MainWindow extends JFrame
{
public MainWindow()
{
super("Fullscreen");
getContentPane().setPreferredSize( Toolkit.getDefaultToolkit().getScreenSize());
pack();
setResizable(false);
show();
SwingUtilities.invokeLater(new Runnable() {
public void run()
{
Point p = new Point(0, 0);
SwingUtilities.convertPointToScreen(p, getContentPane());
Point l = getLocation();
l.x -= p.x;
l.y -= p.y;
setLocation(l);
}
});
}
...
}
You need to use the following API: http://java.sun.com/docs/books/tutorial/extra/fullscreen/index.html
Going full screen isn't as simple as making a large panel, you need to look into the underlying OS graphics. But your JPanel code should translate just fine.
I needed to search a lot, to do the same. Here is completely a working version of it by steps, so that i can find it later also, and use it.
Step 1: create a file called fullscreen.java
Step 2: copy this code and paste it as it is:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class fullscreen extends Window
{
private Button button;
public fullscreen()
{
super(new Frame());
button = new Button("Close");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
setLayout(new FlowLayout());
add(button);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setBounds(0,0,screenSize.width, screenSize.height);
}
public static void main(String[] args)
{
// This will take over your whole screen tested and works in my:
// Fedora 12/13/14
// CentOS 5.0
// if this works for you, in other platforms, please leave a comments which OS it worked.
// happy coding!
new fullscreen().setVisible(true);
}
}
Step 3: compile the code and run
Done.
If I were you I would try to make Java not draw the border of the Jframe, then make it take all the screen.
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import javax.swing.JFrame;
public class FenNoBorder extends JFrame {
public FenNoBorder () {
setUndecorated(true);
setVisible(true);
GraphicsEnvironment graphicsEnvironment=GraphicsEnvironment.getLocalGraphicsEnvironment();
Rectangle maximumWindowBounds=graphicsEnvironment.getMaximumWindowBounds();
setBounds(maximumWindowBounds);
}
}

Categories

Resources