Graphics Rendering in Title Bar

Only Title bar shows, the JFrame is not showing

Take a look at the difference between

public static final int HEIGH = 600;

and

frame.setSize(WIDTH, HEIGHT);

Canvas indirectly defines two public static fields called WIDTH and HEIGHT set to 1 and 2 respectively

A better solution would be to override Canvass getPreferredSize method and return the preferred size you want...

@Override
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}

The you can just use pack

Display game = new Display();
JFrame frame = new JFrame();
frame.add(game);
frame.pack();
frame.setTitle(TITLE);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);

A word or warning against using setSize on a top level container. A window normally contains frame decorations, these are included WITHIN the windows bounds. If you use setSize, you are reducing the content area by the amount of window decorations, which will result in a smaller then expected size. Instead, you should override the getPreferredSize method of your main container and call pack. This allows the window to "pack" itself around the content, but leave space for the frame decorations, preserving the space you have requested.

FrameSetup

You can also have a look at:

  • How to get JPanel equal width and height
  • How to get the EXACT middle of a screen, even when re-sized
  • Graphics rendering in title bar
  • How can I set in the midst?

For more details

Java Upper Boundary Graphics

Its the height of title bar of JFrame that's why y starts visible after 22.

Same for x that starts visible from 2 due to JFrame outer border width.

Here is the sample code along with snapshot

    g.setColor(Color.RED);
g.drawRect(3, 22, 200, 200);

Sample Image

--EDIT--

I never suggest you to use it. Read below comments for it's drawbacks.

Program icon looks curious in the title bar when using a VCL style

This is known issue with VCL Styles http://qc.embarcadero.com/wc/qcmain.aspx?d=106224

Also see this issue in Embarcadero's newer QC site: https://quality.embarcadero.com/browse/RSP-11572 --- it's been 3 years since initially reported, and still not fixed. If enough people vote for that issue, maybe it will get some attention.

As workaround you can load proper 16x16 icon into form's Icon property.

In order for that to work you have to also set Application.MainFormOnTaskBar := false; in your .dpr file

However that has some other undesirable effects because it will disable Windows Vista or Windows 7 Aero effects, including live taskbar thumbnails, Dynamic Windows, Windows Flip, and Windows Flip 3D. See: MainFormOnTaskBar

In any case do not change your application icon size because it is the worst solution.

Is it possible to customize main JFrame title rendering in Swing?

You cannot modify system native frames/dialogs decorations (including frame/dialog title).

Though there are two ways to modify the whole frame/dialog decoration:

  1. You have to use some specific L&F in your application that has custom frame/dialog decorations and allows to change it - i don't really know if there is such. (you can find many L&Fs that have their own frame/dialog decorations, for example this one)

  2. You have to install your own RootPaneUI that will customize frame decoradion, but be aware that you will have to write all of the frame/dialog decoration features on your own (including window drag and resize, control buttons, title and others) - that requires a good knowledge of UIs, graphics and Swing.

Java and Windows 8 Toolbar

The issue has nothing to do with Windows 8, but the fact that you've overridden paint of a top level container.

The frame border is painting within the bounds of the window.

A frame has a content pane which should be used to layout the contents or perform custom painting.

Instead of overriding paint of the top level container, create your self a custom component (extending from something like JPanel) and override it's paintComponent method.

You can then either add it to the frames content pane or replace the frames content pane

Check out...

  • Performing Custom Painting
  • Painting in AWT and Swing
  • Java graphic image
  • How can I set in the midst?
  • How to get the EXACT middle of a screen, even when re-sized
  • Graphics rendering in title bar

For further explanations

JPanel position whacked by BufferStrategy

Swing uses it's own rendering engine, which is a passive implementation. You're attempting to circumvent this with your own, active, rendering engine, the two are going to butt heads.

Because the BufferStrategy belongs to the JFrame, it's created within the confines of it, so 0x0 will be the top left position of the JFrame, not the JPanel.

Swing's rendering engine will do this translation automatically for you.

You have two basic choices.

  1. Don't base the rendering off a JPanel and simply have a "render" class which does this independently (and use a Canvas instead of the JFrame as the bases for the BufferStrategy)
  2. Use a Swing Timer as the primary rendering engine

Swing Timer based example...

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Test {

public static void main(String[] args) {
new Test();
}

public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new ViewPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public static class ViewPanel extends JPanel {

private static int APP_WIDTH = 600;
private static int APP_HEIGHT = 400;

private static final long serialVersionUID = -8019663913250286271L;

public ViewPanel() {
setBackground(Color.GRAY);
Timer timer = new Timer(5, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
repaint();
}
});
timer.start();
}

public void init() {
}

@Override
public Dimension getPreferredSize() {
return new Dimension(APP_HEIGHT, APP_HEIGHT);
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
render(g);
}

// Where I do the drawing. It's called from the rendering loop in the JFrame
public void render(Graphics g) {

// refresh the background since we're not relying on paintComponent all the time
Color bgc = getBackground();
g.setColor(bgc);
g.fillRect(0, 0, APP_WIDTH, APP_HEIGHT);

// just paint a moving box
drawBox(g);

// draw a line to prove correctness. In the loop, you can see part of this line is hidden
// underneath the title bar
g.setColor(Color.red);
g.drawLine(0, 0, APP_WIDTH, APP_HEIGHT);
}

protected void drawBox(Graphics g) {

// get a random color
Random ran = new Random();
int red = ran.nextInt(255);
int grn = ran.nextInt(255);
int ble = ran.nextInt(255);
Color colour = new Color(red, grn, ble);
g.setColor(colour);

// get a random position
int x = ran.nextInt(APP_WIDTH - 50);
int y = ran.nextInt(APP_HEIGHT - 50);

// draw it
g.fillRect(x, y, 50, 50);
}
}
}


Related Topics



Leave a reply



Submit