Edited with a SSCCE and a workaround
I want to programmatically change the location of a JDialog.
public class SSCCE {
public static void main(String[] pArgs) {
JDialog dialog = new JDialog();
dialog.setSize(300, 300);
dialog.setLocation(10, 10);
dialog.setVisible(true);
}
}
However, this is not working, the new dialog is always located in the center of the screen. I suspect it has something todo with my L&F (Windows 7 64bit, jdk 1.6_30), when setting the dialog to be undecorated,
public class SSCCEWorksButUndecorated {
public static void main(String[] pArgs) {
JDialog dialog = new JDialog();
dialog.setSize(300, 300);
dialog.setLocation(10, 10);
dialog.setUndecorated(true);
dialog.getRootPane().setWindowDecorationStyle(JRootPane.PLAIN_DIALOG);
dialog.setVisible(true);
}
}
The location is excalty where I specified.
But I need a decorated dialog, has anyone else seen this problem before or am I missing something?
Workaround by settings location after setVisible() for modal dialogs
public class SSCCEWorkaroundForModalDialogs {
public static void main(String[] pArgs) {
final JDialog dialog = new JDialog();
dialog.setSize(300, 300);
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
dialog.setLocation(10, 10);
}
});
dialog.setVisible(true);
}
}
The move method documentation says:
This method changes layout-related information, and therefore,
invalidates the component hierarchy.
The method changes the geometry-related data. Therefore, the native
windowing system may ignore such requests, or it may modify the
requested data, so that the Window object is placed and sized in a way
that corresponds closely to the desktop settings.
I assume you can do a call to revalidaite() before setting the dialog visible again.
I did it my way -
package com.whodesire.element;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.KeyStroke;
public class MessageEdge {
private JDialog messageEdge = null;
private JDialog tempMessage = null;
private Point elmLoc = null;
private String[] option;
private JButton btnOK;
private JLayeredPane lp = null;
private int top = 70;
MessageEdge(JFrame owner){
owner.setAlwaysOnTop(false);
}
public void ShowMessage(final String msg){
ShowMessage(msg, "OK");
}
public void ShowMessage(final String msg, final String... option){
this.option = option;
init();
}
protected void setRootPaneStroking(JRootPane rootPane){
rootPane.setWindowDecorationStyle(JRootPane.NONE);
KeyStroke stroke = KeyStroke.getKeyStroke("ESCAPE");
Action action = new AbstractAction() {
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
disposeMessage();
}
};
InputMap inputMap = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
inputMap.put(stroke, "ESCAPE");
rootPane.getActionMap().put("ESCAPE", action);
};
private void init(){
top = 70;
tempMessage = new JDialog(){
private static final long serialVersionUID = 1L;
{
setUndecorated(true);
setType(Type.UTILITY);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setBackground(new Color(0, 0, 0, 0));
elmLoc = Elementos.getElementosLocationPoint();
setSize(460, 57);
setLayout(new GridLayout(1, 1));
if(lp == null)
lp = getModelJLayeredPane();
add(lp);
setLocation(elmLoc.x-10, elmLoc.y+top);
setAlwaysOnTop(true);
validate();
setVisible(true);
}
};
new Thread(new Runnable(){
public void run(){
try{
OneMethod.playSound("catchyMessage");
whileLoop:
while(true){
//System.out.println("top value is : " + top + ", is top value bigger than -47 : " + (top > -47));
if(top > -47){
top -= 7;
tempMessage.setLocation(elmLoc.x-10, elmLoc.y+top);
}else{
top = -47;
initMessageEdge();
break whileLoop;
}
Thread.sleep(4);
}
}catch(InterruptedException ie){
ie.printStackTrace();
}
}
}).start();
}
private void initMessageEdge(){
tempMessage.setVisible(false);
tempMessage.remove(lp);
tempMessage.dispose();
//Elementos is my JFrame
messageEdge = new JDialog(Elementos.getFrame(), true){
private static final long serialVersionUID = 1L;
{
setUndecorated(true);
setType(Type.UTILITY);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setRootPaneStroking(getRootPane());
setBackground(new Color(0, 0, 0, 0));
requestFocusInWindow();
elmLoc = Elementos.getElementosLocationPoint();
setSize(460, 57);
setLayout(new GridLayout(1, 1));
if(lp == null)
lp = getModelJLayeredPane();
add(lp);
setLocation(elmLoc.x-10, elmLoc.y+top);
setAlwaysOnTop(true);
validate();
}
};
messageEdge.setVisible(true);
messageEdge.requestFocus();
}
private JLayeredPane getModelJLayeredPane(){
JLayeredPane layer = new JLayeredPane();
layer.setBounds(0, 0, 460, 57);
layer.setLayout(null);
JPanel panel = new JPanel(){
private static final long serialVersionUID = 1L;
public void paintComponent(Graphics gr){
super.paintComponent(gr);
Graphics2D g = (Graphics2D) gr;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, 0.01f));
g.setColor(new Color(255, 196, 51));
g.fillRect(0, 0, 460, 57);
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.75f));
g.setColor(new Color(255, 196, 51));
g.fillRect(0, 0, 460, 47);
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
g.setColor(new Color(244, 171, 50));
int[] xxPoly = {0, 10, 10};
int[] yyPoly = {47, 47, 57};
Polygon pplg = new Polygon(xxPoly, yyPoly, xxPoly.length);
g.fillPolygon(pplg);
}
};
panel.setSize(450, 57);
panel.setOpaque(true);
panel.setLayout(null);
layer.add(panel);
btnOK = new JButton(){
private static final long serialVersionUID = 1L;
#Override
protected void paintComponent(Graphics gr) {
final Graphics2D g = (Graphics2D) gr.create();
g.setPaint(new GradientPaint(new Point(0, 0), Color.WHITE,
new Point(0, getHeight()), new Color(255, 196, 51)));
g.fillRect(0, 0, getWidth(), getHeight());
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setColor(Color.BLACK);
g.setFont(new Font(OneMethod.getSegoeUIBoldFont().getFamily(), Font.BOLD, 11));
g.drawString(option[0], 8, 17);
g.dispose();
super.paintComponent(g);
}
};
btnOK.setFocusPainted(false);
btnOK.setBorder(BorderFactory.createLineBorder(new Color(244, 171, 50)));
btnOK.setBounds(460-30, (int)((47/2)-(25/2)), 30, 25);
layer.add(btnOK);
btnOK.addMouseListener(new MouseAdapter(){
#Override
public void mousePressed(MouseEvent evt){
btnOK.setBorder(BorderFactory.createEmptyBorder());
btnOK.setBorder(BorderFactory.createLoweredBevelBorder());
}
#Override
public void mouseReleased(MouseEvent evt){
btnOK.setBorder(BorderFactory.createLineBorder(new Color(244, 171, 50)));
disposeMessage();
Elementos.getFrame().setAlwaysOnTop(true);
}
});
layer.moveToFront(btnOK);
return layer;
}
private void disposeMessage(){
messageEdge.setModal(false);
messageEdge.setVisible(false);
messageEdge.dispose();
}
}
Hope it may help you and others, Cheers...
Related
I am developing the game GUI now.
But I have a small problem during programming.
I make a button to start and centered the button.
And I override mouseEntered and mouseExited.
When I run the program, Image is positioned center but cursor reacted from a distance.
I don't know why image and cursor are not matched...
This is my Main code.
package PoET;
public class Main {
public static final int SCREEN_WIDTH=600;
public static final int SCREEN_HEIGHT=800;
public static void main(String[] args) {
// TODO Auto-generated method stub
new Display();
}
}
And this is my Display code.
package PoET;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Display extends JFrame {
private Image screenImage;
private Graphics screenGraphic;
private Image explainImage = new ImageIcon(Main.class.getResource("../images/explainSample.jpg")).getImage();
private Image introBackground = new ImageIcon(Main.class.getResource("../images/background.jpg")).getImage();
private JLabel menuBar = new JLabel(new ImageIcon(Main.class.getResource("../images/menuBar.png")));
private ImageIcon quitButtonBasicImage = new ImageIcon(Main.class.getResource("../images/quitButtonBasic.png"));
private ImageIcon quitButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/quitButtonPressed.png"));
private ImageIcon startButtonBasicImage = new ImageIcon(Main.class.getResource("../images/startButtonBasic.png"));
private ImageIcon startButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/startButtonEntered.png"));
private ImageIcon developerButtonBasicImage = new ImageIcon(Main.class.getResource("../images/developerButtonBasic.png"));
private ImageIcon developerButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/developerButtonEntered.png"));
private ImageIcon goButtonBasicImage = new ImageIcon(Main.class.getResource("../images/startButtonBasic.png"));
private ImageIcon goButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/startButtonEntered.png"));
private JButton quitButton = new JButton(
quitButtonBasicImage);
private JButton startButton = new JButton(
startButtonBasicImage);
private JButton developerButton = new JButton(
developerButtonBasicImage);
private JButton goButton = new JButton(
new ImageIcon(Main.class.getResource("../images/startButtonEntered.png")));
private int mouseX, mouseY;
private boolean isExplainScreen=false;
public Display() {
setUndecorated(true);
setTitle("RogueLike PoET");
setSize(Main.SCREEN_WIDTH, Main.SCREEN_HEIGHT);
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setBackground(new Color(0, 0, 0, 0));
setLayout(null);
//quitButton.setBounds(560, 30, 30, 30);
quitButton.setBounds(400, 200, 30, 30);
quitButton.setBorderPainted(false);
quitButton.setContentAreaFilled(false);
quitButton.setFocusPainted(false);
quitButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
quitButton.setIcon(quitButtonEnteredImage);
quitButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
}
#Override
public void mouseExited(MouseEvent e) {
quitButton.setIcon(quitButtonBasicImage);
quitButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
}
#Override
public void mousePressed(MouseEvent e) {
System.exit(0);
}
});
add(quitButton);
menuBar.setBounds(0, 0, 600, 30);
menuBar.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
mouseX=e.getX();
mouseY=e.getY();
}
});
menuBar.addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
int x=e.getXOnScreen();
int y=e.getYOnScreen();
setLocation(x-mouseX,y-mouseY);
}
});
add(menuBar);
startButton.setBounds(150, 540, 300, 60);
startButton.setBorderPainted(false);
startButton.setContentAreaFilled(false);
startButton.setFocusPainted(false);
startButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
startButton.setIcon(startButtonEnteredImage);
startButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
}
#Override
public void mouseExited(MouseEvent e) {
startButton.setIcon(startButtonBasicImage);
startButton.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
#Override
public void mousePressed(MouseEvent e) {
startButton.setVisible(false);
goButton.setVisible(true);
introBackground=new ImageIcon(Main.class.getResource("../images/background2.jpg")).getImage();
isExplainScreen=true;
}
});
add(startButton);
developerButton.setBounds(150, 610, 300, 60);
developerButton.setBorderPainted(false);
developerButton.setContentAreaFilled(false);
developerButton.setFocusPainted(false);
developerButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
developerButton.setIcon(developerButtonEnteredImage);
developerButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
}
#Override
public void mouseExited(MouseEvent e) {
developerButton.setIcon(developerButtonBasicImage);
developerButton.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
#Override
public void mousePressed(MouseEvent e) {
developerButton.setVisible(false);
goButton.setVisible(true);
introBackground=new ImageIcon(Main.class.getResource("../images/background2.jpg")).getImage();
isExplainScreen=false;
}
});
add(developerButton);
goButton.setVisible(false);
goButton.setBounds(150, 720, 300, 60);
goButton.setBorderPainted(false);
goButton.setContentAreaFilled(false);
goButton.setFocusPainted(false);
goButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
goButton.setIcon(goButtonEnteredImage);
goButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
}
#Override
public void mouseExited(MouseEvent e) {
goButton.setIcon(goButtonBasicImage);
goButton.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
#Override
public void mousePressed(MouseEvent e) {
goButton.setVisible(false);
introBackground=new ImageIcon(Main.class.getResource("../images/background2.jpg")).getImage();
isExplainScreen=true;
}
});
add(goButton);
Music introMusic = new Music("introMusic.mp3", true);
introMusic.start();
}
public void paint(Graphics g) {
screenImage = createImage(Main.SCREEN_WIDTH, Main.SCREEN_HEIGHT);
screenGraphic = screenImage.getGraphics();
screenDraw(screenGraphic);
g.drawImage(screenImage, 0, 0, null);
}
public void screenDraw(Graphics g) {
g.drawImage(introBackground, 0, 0, null);
paintComponents(g);
if(isExplainScreen) {
g.drawImage(explainImage, 50, 50,null);
}
this.repaint();
}
}
So I stripped back your example, removed the MouseListeners and just set the cursor of the buttons and it works fine - I reset the buttons to paint their border and contents so I could see their extent, and the cursor changes when ever the mouse enters/exist the area they cover without issue
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Display extends JFrame {
public static final int SCREEN_WIDTH = 600;
public static final int SCREEN_HEIGHT = 800;
public static void main(String[] args) {
// TODO Auto-generated method stub
new Display();
}
private Image screenImage;
private Graphics screenGraphic;
// private Image explainImage = new ImageIcon(Main.class.getResource("../images/explainSample.jpg")).getImage();
// private Image introBackground = new ImageIcon(Main.class.getResource("../images/background.jpg")).getImage();
// private JLabel menuBar = new JLabel(new ImageIcon(Main.class.getResource("../images/menuBar.png")));
//
// private ImageIcon quitButtonBasicImage = new ImageIcon(Main.class.getResource("../images/quitButtonBasic.png"));
// private ImageIcon quitButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/quitButtonPressed.png"));
//
// private ImageIcon startButtonBasicImage = new ImageIcon(Main.class.getResource("../images/startButtonBasic.png"));
// private ImageIcon startButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/startButtonEntered.png"));
// private ImageIcon developerButtonBasicImage = new ImageIcon(Main.class.getResource("../images/developerButtonBasic.png"));
// private ImageIcon developerButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/developerButtonEntered.png"));
//
// private ImageIcon goButtonBasicImage = new ImageIcon(Main.class.getResource("../images/startButtonBasic.png"));
// private ImageIcon goButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/startButtonEntered.png"));
private JButton quitButton = new JButton(
"Quote");
private JButton startButton = new JButton(
"Start");
private JButton developerButton = new JButton(
"Developer");
private JButton goButton = new JButton(
new ImageIcon("Go"));
private int mouseX, mouseY;
private boolean isExplainScreen = false;
public Display() {
setUndecorated(true);
setTitle("RogueLike PoET");
setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
// setBackground(new Color(0, 0, 0, 0));
setLayout(null);
//quitButton.setBounds(560, 30, 30, 30);
quitButton.setBounds(400, 200, 30, 30);
// quitButton.setBorderPainted(false);
// quitButton.setContentAreaFilled(false);
quitButton.setFocusPainted(false);
quitButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
add(quitButton);
startButton.setBounds(150, 540, 300, 60);
// startButton.setBorderPainted(false);
// startButton.setContentAreaFilled(false);
startButton.setFocusPainted(false);
startButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
add(startButton);
developerButton.setBounds(150, 610, 300, 60);
// developerButton.setBorderPainted(
// false);
// developerButton.setContentAreaFilled(
// false);
developerButton.setFocusPainted(
false);
developerButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
add(developerButton);
goButton.setVisible(
false);
goButton.setBounds(
150, 720, 300, 60);
// goButton.setBorderPainted(
// false);
// goButton.setContentAreaFilled(
// false);
goButton.setFocusPainted(
false);
goButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
add(goButton);
}
public void paint(Graphics g) {
screenImage = createImage(SCREEN_WIDTH, SCREEN_HEIGHT);
screenGraphic = screenImage.getGraphics();
screenDraw(screenGraphic);
g.drawImage(screenImage, 0, 0, null);
}
public void screenDraw(Graphics g) {
// g.drawImage(introBackground, 0, 0, null);
paintComponents(g);
if (isExplainScreen) {
// g.drawImage(explainImage, 50, 50, null);
}
this.repaint();
}
}
Observations
Don't override paint of a top level container like a JFrame. JFrame is a compound component (it has a series of child components which make up it's core functionality), overriding paint can have an adverse affect on how those components get painted. Unlike top level containers, Swing components are double buffered by default.
Also, the "viewable" area the "window" area are two different concepts. For more details see How to get the EXACT middle of a screen, even when re-sized
Also, you could be painting beneath the windows decorations (I know, it's a undecorated window, but it's still a bad habit)
Don't try and put ALL your logic into a single class/paint method. Instead, break down your screens into separate components and use something like CardLayout to switch between them
This...
setSize(Main.SCREEN_WIDTH, Main.SCREEN_HEIGHT);
is generally a bad idea. Better to let the child components dictate their preferred sizes and simply pack the window around them
Don't call setVisible(true); before you've established the basic UI, otherwise it's possible for some components not to be painted
I'm not sure what befit you're hoping to get from setBackground(new Color(0, 0, 0, 0));, but based on your current design, it seems like a waste
Don't call this.repaint(); or perform any other operation inside the paint chain which might trigger a repaint. This will set you for a infinite loop which will eventually consume all your CPU cycles
setLayout(null); is ill advised - there is a lot going into how components get laid out, you're in for a lot of work to reproduce it
Instead, it might look something like (as a starting point)...
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Display());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class Display extends JPanel {
// private Image explainImage = new ImageIcon(Main.class.getResource("../images/explainSample.jpg")).getImage();
// private Image introBackground = new ImageIcon(Main.class.getResource("../images/background.jpg")).getImage();
// private JLabel menuBar = new JLabel(new ImageIcon(Main.class.getResource("../images/menuBar.png")));
//
// private ImageIcon quitButtonBasicImage = new ImageIcon(Main.class.getResource("../images/quitButtonBasic.png"));
// private ImageIcon quitButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/quitButtonPressed.png"));
//
// private ImageIcon startButtonBasicImage = new ImageIcon(Main.class.getResource("../images/startButtonBasic.png"));
// private ImageIcon startButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/startButtonEntered.png"));
// private ImageIcon developerButtonBasicImage = new ImageIcon(Main.class.getResource("../images/developerButtonBasic.png"));
// private ImageIcon developerButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/developerButtonEntered.png"));
//
// private ImageIcon goButtonBasicImage = new ImageIcon(Main.class.getResource("../images/startButtonBasic.png"));
// private ImageIcon goButtonEnteredImage = new ImageIcon(Main.class.getResource("../images/startButtonEntered.png"));
private JButton quitButton = new JButton(
"Quote");
private JButton startButton = new JButton(
"Start");
private JButton developerButton = new JButton(
"Developer");
private JButton goButton = new JButton(
new ImageIcon("Go"));
private int mouseX, mouseY;
private boolean isExplainScreen = false;
public Display() {
setLayout(null);
//quitButton.setBounds(560, 30, 30, 30);
quitButton.setBounds(400, 200, 30, 30);
// quitButton.setBorderPainted(false);
// quitButton.setContentAreaFilled(false);
quitButton.setFocusPainted(false);
quitButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
add(quitButton);
startButton.setBounds(150, 540, 300, 60);
// startButton.setBorderPainted(false);
// startButton.setContentAreaFilled(false);
startButton.setFocusPainted(false);
startButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
add(startButton);
developerButton.setBounds(150, 610, 300, 60);
// developerButton.setBorderPainted(
// false);
// developerButton.setContentAreaFilled(
// false);
developerButton.setFocusPainted(
false);
developerButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
add(developerButton);
goButton.setVisible(
false);
goButton.setBounds(
150, 720, 300, 60);
// goButton.setBorderPainted(
// false);
// goButton.setContentAreaFilled(
// false);
goButton.setFocusPainted(
false);
goButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
add(goButton);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(600, 800);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(introBackground, 0, 0, null);
// This should be done else where
// if (isExplainScreen) {
// // g.drawImage(explainImage, 50, 50, null);
// }
//this.repaint();
}
}
}
I've done several inspection and done research on how to make a single panel transparent so that the image underneath it will show but has been unsuccessful with panels on a JTabbedPane. I have setOpaque(false) and setBackground(new Color(0,0,0,20)) on both the panels of the JTabbedPane and also did the same on the JTabbedPane itself. However, I still can't get the image on the back of the tabbed pane to show. What else am I missing here?
tabbePane.java
package tabbedpanetransparencypractice;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.*;
public class tabbedPane extends JTabbedPane{
JPanel tab1panel = new JPanel();
JPanel tab2panel = new JPanel();
public tabbedPane(){
this.setPreferredSize(new Dimension(400,400));
this.setBackground(new Color(0,0,0,20));
this.setOpaque(false);
tab1panel.setBackground(new Color(0,0,0,20));
tab2panel.setBackground(new Color(0,0,0,20));
tab1panel.setOpaque(false);
tab2panel.setOpaque(false);
this.addTab("Tab 1", tab1panel);
this.addTab("Tab 2", tab2panel);
}
}
topPanel.java
package tabbedpanetransparencypractice;
import javax.swing.*;
import java.awt.*;
public class topPanel extends JPanel{
Image myBG = new ImageIcon(getClass().getClassLoader().getResource("Assets/loginBg.jpg")).getImage();
#Override
public void paintComponent(Graphics g){
g.drawImage(myBG,0,0,getWidth(),getHeight(),this);
}
public topPanel(){
addTabbedPane();
}
public void addTabbedPane(){
tabbedPane tabbedpane = new tabbedPane();
this.add(tabbedpane);
}
}
frame.java
package tabbedpanetransparencypractice;
import java.awt.Dimension;
import javax.swing.*;
public class frame extends JFrame{
topPanel myPanel = new topPanel();
public frame(){
this.setPreferredSize(new Dimension(600,600));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.pack();
this.setLocationRelativeTo(null);
addComponents();
}
final void addComponents(){
this.setContentPane(myPanel);
}
}
main.java
package tabbedpanetransparencypractice;
public class main {
public static void main(String[] args) {
frame myFrame = new frame();
}
}
This is the output I get (I want the tab1 and tab2 to be transparent to reveal the bg image underneath)
I'd appreciate any help. Thanks.
First, Swing DOES NOT know how to deal with component's whose background colors are alpha based but which are opaque. Swing only knows how to deal with fully opaque and fully transparent components.
Using alpha based colors will generate weird and random paint artefacts. The simple answer is, you should never apply a alpha based color to a component's background (the only exception is JFrame - thanks Sun :P)
The primary solution is, fake it.
That is, make the component transparent (setOpaque(false)) and paint the background at a reduced alpha level. You can then use a alpha based color (because the component is no longer reliant on the color, as it's transparent), but I tend to just use a AlphaComposite as it's generally easier to control and manipulate.
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
BackgroundPane bp = new BackgroundPane();
bp.setLayout(new BorderLayout());
bp.setBorder(new EmptyBorder(20, 20, 20, 20));
SeeThroughTabbedPane tp = new SeeThroughTabbedPane();
tp.setAlpha(0.5f);
tp.addTab("Tab 1", new TestPane("I be see through"));
tp.addTab("Tab 2", new TestPane("But you can't see me"));
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(bp);
frame.add(tp);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane(String text) {
setOpaque(false);
setLayout(new GridBagLayout());
JLabel label = new JLabel(text);
label.setForeground(Color.WHITE);
add(label);
}
}
public class BackgroundPane extends JPanel {
private BufferedImage bg;
public BackgroundPane() {
try {
bg = ImageIO.read(new File("/Volumes/Disk02/Dropbox/MegaTokyo/megatokyo_omnibus_1_3_cover_by_fredrin-d4oupef 50%.jpg"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public Dimension getPreferredSize() {
return bg == null ? new Dimension(200, 200) : new Dimension(bg.getWidth(), bg.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (bg != null) {
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - bg.getWidth()) / 2;
int y = (getHeight() - bg.getHeight()) / 2;
g2d.drawImage(bg, x, y, this);
g2d.dispose();
}
}
}
public class SeeThroughTabbedPane extends JTabbedPane {
private float alpha;
public SeeThroughTabbedPane() {
setOpaque(false);
setAlpha(1f);
}
public void setAlpha(float value) {
if (alpha != value) {
float old = alpha;
this.alpha = value;
firePropertyChange("alpha", old, alpha);
repaint();
}
}
public float getAlpha() {
return alpha;
}
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(getBackground());
g2d.setComposite(AlphaComposite.SrcOver.derive(getAlpha()));
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.dispose();
super.paintComponent(g);
}
}
}
Remember, anything you added to the JTabbedPane which is still opaque will remain so, not in my TestPane's constructor, I set the panel's opaque state to false
You might also like to take a look at Painting in AWT and Swing and Performing Custom Painting
You might be able to use UIManager.put("TabbedPane.contentAreaColor", new Color(255, 255, 0, 100));
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TransparentTabbedPaneTest {
public JComponent makeUI() {
Color bgc = new Color(110, 110, 0, 100);
Color fgc = new Color(255, 255, 0, 100);
UIManager.put("TabbedPane.shadow", fgc);
UIManager.put("TabbedPane.darkShadow", fgc);
UIManager.put("TabbedPane.light", fgc);
UIManager.put("TabbedPane.highlight", fgc);
UIManager.put("TabbedPane.tabAreaBackground", fgc);
UIManager.put("TabbedPane.unselectedBackground", fgc);
UIManager.put("TabbedPane.background", bgc);
UIManager.put("TabbedPane.foreground", Color.WHITE);
UIManager.put("TabbedPane.focus", fgc);
UIManager.put("TabbedPane.contentAreaColor", fgc);
UIManager.put("TabbedPane.selected", fgc);
UIManager.put("TabbedPane.selectHighlight", fgc);
UIManager.put("TabbedPane.borderHightlightColor", fgc);
JTabbedPane tabs = new JTabbedPane();
JPanel tab1panel = new JPanel();
tab1panel.setBackground(new Color(0, 220, 220, 50));
JPanel tab2panel = new JPanel();
tab2panel.setBackground(new Color(220, 0, 0, 50));
JPanel tab3panel = new JPanel();
tab3panel.setBackground(new Color(0, 0, 220, 50));
JCheckBox cb = new JCheckBox("setOpaque(false)");
cb.setOpaque(false);
tab3panel.add(cb);
tab3panel.add(new JCheckBox("setOpaque(true)"));
tabs.addTab("Tab 1", tab1panel);
tabs.addTab("Tab 2", tab2panel);
tabs.addTab("Tab 3", new AlphaContainer(tab3panel));
JPanel p = new JPanel(new BorderLayout()) {
private Image myBG = new ImageIcon(getClass().getResource("test.png")).getImage();
#Override public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(myBG, 0, 0, getWidth(), getHeight(), this);
}
};
p.add(tabs);
p.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
return p;
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new TransparentTabbedPaneTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
//https://tips4java.wordpress.com/2009/05/31/backgrounds-with-transparency/
class AlphaContainer extends JComponent {
private JComponent component;
public AlphaContainer(JComponent component) {
this.component = component;
setLayout( new BorderLayout() );
setOpaque( false );
component.setOpaque( false );
add( component );
}
/**
* Paint the background using the background Color of the
* contained component
*/
#Override
public void paintComponent(Graphics g) {
g.setColor( component.getBackground() );
g.fillRect(0, 0, getWidth(), getHeight());
}
}
I have set a background image on a JPanel but when i try to add buttons and selects to the custom background panel the buttons are hidden until i move the mouse over the buttons. I have included the code snippets below.
Below is my customized JPanel
package au.com.tankwarz.view.custompanels;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
public class BackgroundPanel extends JPanel
{
/**
*
*/
private static final long serialVersionUID = 1659728640545162103L;
public BackgroundPanel()
{
}
#Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(loadBackgroundImage(), 0, 0, this);
g2d.dispose();
}
private static BufferedImage loadBackgroundImage()
{
BufferedImage bi = new BufferedImage(800, 600, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bi.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Paint a gradient from top to bottom
GradientPaint gp = new GradientPaint( 0, 0, Color.BLACK, 0, 600, new Color(0, 0, 255).darker( ).darker() );
g2d.setPaint( gp );
g2d.fillRect( 0, 0, 800, 600 );
g2d.dispose();
return bi;
}
}
And here is where i try to use it to display the panel with the buttons on it.
package au.com.tankwarz.view;
import java.awt.event.ActionListener;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import org.jdesktop.application.Application;
import au.com.tankwarz.view.custompanels.BackgroundPanel;
import com.cloudgarden.layout.AnchorConstraint;
import com.cloudgarden.layout.AnchorLayout;
public class NewGamePanel extends BackgroundPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
private JLabel numberOfPlayersLable;
private JComboBox numberOfPlayersCB;
private JButton cancelButton;
private JButton createPlayersButton;
private JComboBox numberOfTanksCB;
private JLabel numberOfTanksLable;
private JComboBox numberOfRoundsCB;
private JLabel numberOfRounds;
public static final String[] numberOfPlayersCBValues = new String[] { "Two", "Three", "Four" };
public static final String[] numberOfRoundsCBValues = new String[] { "One", "Two", "Three", "Four" };
public static final String[] numberOfTanksCBValues = new String[] { "One", "Two", "Three", "Four" };
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
//new NewGamePanel();
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new NewGamePanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public NewGamePanel() {
super();
initGUI();
}
private void initGUI() {
try {
AnchorLayout thisLayout = new AnchorLayout();
this.setLayout(thisLayout);
this.setPreferredSize(new java.awt.Dimension(800, 600));
this.setSize(800, 600);
this.setOpaque(true);
this.setName("this");
{
numberOfPlayersLable = new JLabel();
this.add(numberOfPlayersLable, new AnchorConstraint(144, 320, 201, 77, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
numberOfPlayersLable.setName("numberOfPlayersLable");
numberOfPlayersLable.setPreferredSize(new java.awt.Dimension(60, 40));
}
{
ComboBoxModel numberOfPlayersCBModel =
new DefaultComboBoxModel(numberOfPlayersCBValues);
numberOfPlayersCB = new JComboBox();
this.add(numberOfPlayersCB, new AnchorConstraint(125, 697, 219, 386, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
numberOfPlayersCB.setModel(numberOfPlayersCBModel);
numberOfPlayersCB.setPreferredSize(new java.awt.Dimension(60, 40));
}
{
numberOfRounds = new JLabel();
this.add(numberOfRounds, new AnchorConstraint(298, 371, 355, 77, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
numberOfRounds.setName("numberOfRounds");
numberOfRounds.setPreferredSize(new java.awt.Dimension(60, 40));
}
{
ComboBoxModel numberOfRoundsCBModel =
new DefaultComboBoxModel(numberOfRoundsCBValues);
numberOfRoundsCB = new JComboBox();
this.add(numberOfRoundsCB, new AnchorConstraint(283, 697, 366, 386, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
numberOfRoundsCB.setModel(numberOfRoundsCBModel);
numberOfRoundsCB.setName("numberOfRoundsCB");
numberOfRoundsCB.setPreferredSize(new java.awt.Dimension(60, 40));
}
{
numberOfTanksLable = new JLabel();
this.add(numberOfTanksLable, new AnchorConstraint(453, 320, 509, 77, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
numberOfTanksLable.setName("numberOfTanksLable");
numberOfTanksLable.setPreferredSize(new java.awt.Dimension(60, 40));
}
{
ComboBoxModel numberOfTanksCBModel =
new DefaultComboBoxModel(numberOfTanksCBValues);
numberOfTanksCB = new JComboBox();
this.add(numberOfTanksCB, new AnchorConstraint(437, 697, 520, 386, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
numberOfTanksCB.setModel(numberOfTanksCBModel);
numberOfTanksCB.setPreferredSize(new java.awt.Dimension(60, 40));
}
{
createPlayersButton = new JButton();
this.add(createPlayersButton, new AnchorConstraint(795, 758, 878, 511, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
createPlayersButton.setName("createPlayersButton");
createPlayersButton.setPreferredSize(new java.awt.Dimension(99, 25));
}
{
cancelButton = new JButton();
this.add(cancelButton, new AnchorConstraint(795, 248, 878, 128, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
cancelButton.setName("cancelButton");
cancelButton.setPreferredSize(new java.awt.Dimension(48, 25));
}
Application.getInstance().getContext().getResourceMap(getClass()).injectComponents(this);
} catch (Exception e) {
e.printStackTrace();
}
}
public void setCreatePlayersButtonActionListener(ActionListener actionListener)
{
createPlayersButton.addActionListener(actionListener);
}
public void setCancelButtonActionListener(ActionListener actionListener)
{
cancelButton.addActionListener(actionListener);
}
public JComboBox getNumberOfPlayersCB()
{
return numberOfPlayersCB;
}
public void setNumberOfPlayersCB(JComboBox numberOfPlayersCB)
{
this.numberOfPlayersCB = numberOfPlayersCB;
}
public JComboBox getNumberOfTanksCB()
{
return numberOfTanksCB;
}
public void setNumberOfTanksCB(JComboBox numberOfTanksCB)
{
this.numberOfTanksCB = numberOfTanksCB;
}
public JComboBox getNumberOfRoundsCB()
{
return numberOfRoundsCB;
}
public void setNumberOfRoundsCB(JComboBox numberOfRoundsCB)
{
this.numberOfRoundsCB = numberOfRoundsCB;
}
}
Any help would be appreciate as i have been struggling with this for a while.
Don't change the state of the component from within any paintXxx method, this could cause a repaint event to be triggered, repeating the process until your CPU is running hot.
Never change the opacity state of the component from within any paintXxx, this will cause a cascading series of repaint's as Swing suddenly starts trying to figure out what components are now visible behind the current one...
Don't dispose of a Graphics context you didn't create, doing so could prevent what ever you paint after it not to be rendered on some systems.
Try not to create the background image on each paint cycle, this is not only expensive from memory point of view, but also expensive from a time point of view
I'm not sure why you flipping the opacity state, you don't really want it to be transparent. Simply call super.paintComponent to prepare the graphics state and then draw your image on top.
You should also avoid using setPreferredSize, see Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? for more details...
Just illustrate the point, this is what you code produces (after I corrected the paint issues)
This is what my test code produces
Updated with test code
import com.apple.eawt.Application;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.RenderingHints;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class BackgroundPanel extends JPanel {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//new NewGamePanel();
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new NewGamePanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public BackgroundPanel() {
}
private static BufferedImage bi;
#Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(loadBackgroundImage(), 0, 0, this);
g2d.dispose();
}
private static BufferedImage loadBackgroundImage() {
if (bi == null) {
bi = new BufferedImage(800, 600, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bi.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Paint a gradient from top to bottom
GradientPaint gp = new GradientPaint(0, 0, Color.BLACK, 0, 600, new Color(0, 0, 255).darker().darker());
g2d.setPaint(gp);
g2d.fillRect(0, 0, 800, 600);
g2d.dispose();
}
return bi;
}
public static class NewGamePanel extends BackgroundPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
private JLabel numberOfPlayersLable;
private JComboBox numberOfPlayersCB;
private JButton cancelButton;
private JButton createPlayersButton;
private JComboBox numberOfTanksCB;
private JLabel numberOfTanksLable;
private JComboBox numberOfRoundsCB;
private JLabel numberOfRounds;
public static final String[] numberOfPlayersCBValues = new String[]{"Two", "Three", "Four"};
public static final String[] numberOfRoundsCBValues = new String[]{"One", "Two", "Three", "Four"};
public static final String[] numberOfTanksCBValues = new String[]{"One", "Two", "Three", "Four"};
public NewGamePanel() {
super();
initGUI();
}
private void initGUI() {
try {
GridBagLayout thisLayout = new GridBagLayout();
this.setLayout(thisLayout);
this.setPreferredSize(new java.awt.Dimension(800, 600));
this.setSize(800, 600);
this.setOpaque(true);
this.setName("this");
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = gbc.REMAINDER;
{
numberOfPlayersLable = new JLabel();
this.add(numberOfPlayersLable, gbc);
numberOfPlayersLable.setName("numberOfPlayersLable");
}
{
ComboBoxModel numberOfPlayersCBModel
= new DefaultComboBoxModel(numberOfPlayersCBValues);
numberOfPlayersCB = new JComboBox();
this.add(numberOfPlayersCB, gbc);
numberOfPlayersCB.setModel(numberOfPlayersCBModel);
}
{
numberOfRounds = new JLabel();
this.add(numberOfRounds, gbc);
numberOfRounds.setName("numberOfRounds");
}
{
ComboBoxModel numberOfRoundsCBModel
= new DefaultComboBoxModel(numberOfRoundsCBValues);
numberOfRoundsCB = new JComboBox();
this.add(numberOfRoundsCB, gbc);
numberOfRoundsCB.setModel(numberOfRoundsCBModel);
numberOfRoundsCB.setName("numberOfRoundsCB");
}
{
numberOfTanksLable = new JLabel();
this.add(numberOfTanksLable, gbc);
numberOfTanksLable.setName("numberOfTanksLable");
}
{
ComboBoxModel numberOfTanksCBModel
= new DefaultComboBoxModel(numberOfTanksCBValues);
numberOfTanksCB = new JComboBox();
this.add(numberOfTanksCB, gbc);
numberOfTanksCB.setModel(numberOfTanksCBModel);
}
{
createPlayersButton = new JButton();
this.add(createPlayersButton, gbc);
createPlayersButton.setName("createPlayersButton");
}
{
cancelButton = new JButton();
this.add(cancelButton, gbc);
cancelButton.setName("cancelButton");
}
// Application.getInstance().getContext().getResourceMap(getClass()).injectComponents(this);
} catch (Exception e) {
e.printStackTrace();
}
}
public void setCreatePlayersButtonActionListener(ActionListener actionListener) {
createPlayersButton.addActionListener(actionListener);
}
public void setCancelButtonActionListener(ActionListener actionListener) {
cancelButton.addActionListener(actionListener);
}
public JComboBox getNumberOfPlayersCB() {
return numberOfPlayersCB;
}
public void setNumberOfPlayersCB(JComboBox numberOfPlayersCB) {
this.numberOfPlayersCB = numberOfPlayersCB;
}
public JComboBox getNumberOfTanksCB() {
return numberOfTanksCB;
}
public void setNumberOfTanksCB(JComboBox numberOfTanksCB) {
this.numberOfTanksCB = numberOfTanksCB;
}
public JComboBox getNumberOfRoundsCB() {
return numberOfRoundsCB;
}
public void setNumberOfRoundsCB(JComboBox numberOfRoundsCB) {
this.numberOfRoundsCB = numberOfRoundsCB;
}
}
}
I want to draw a line in a JPanel.
This is my GUI and I want a line in the JPanel in white.
I find many examples but the problem is the how to use it.
In many exmples, always they draw in a JFrame that extends from a JPanel.
I want to add the Panel to the Frame and add some buttons to draw lines in many directions and use the X button in center to clean the JPanel.
This is the code of the interface:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.Color;
import javax.swing.JScrollPane;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class circuit extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
circuit frame = new circuit();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public circuit() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 559, 332);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(10, 21, 359, 255);
contentPane.add(scrollPane);
JPanel panel = new JPanel();
scrollPane.setViewportView(panel);
panel.setBackground(Color.WHITE);
JLabel label = new JLabel("New label");
label.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
/////////////
}
});
label.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\up.png"));
label.setBounds(447, 66, 46, 48);
contentPane.add(label);
JLabel label_1 = new JLabel("New label");
label_1.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\down.png"));
label_1.setBounds(447, 159, 46, 48);
contentPane.add(label_1);
JLabel label_2 = new JLabel("New label");
label_2.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\right.png"));
label_2.setBounds(495, 112, 46, 48);
contentPane.add(label_2);
JLabel label_3 = new JLabel("New label");
label_3.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\left.png"));
label_3.setBounds(398, 112, 46, 48);
contentPane.add(label_3);
JLabel label_4 = new JLabel("New label");
label_4.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\1303860240_list-remove.png"));
label_4.setBounds(447, 112, 46, 48);
contentPane.add(label_4);
}
}
This is the code to draw a line
public void paint(Graphics graphics)
{
graphics.drawLine(10, 20, 300, 310);
}
So how to use this lines ....
Thanks in advance.
Best regards,
Ali
It may be easier to draw lines using the following approach:
click to mark the first endpoint
drag to show the line in progress
release to mark the second endpoint
This related example may offer some additional guidance.
Addendum
The example below implements the outline above.
I've update the example to show how to use a panel of buttons to affect the drawing.
See also this related example that uses the Action interface with key bindings.
I've updated this example to use Key Bindings.
LinePanel.java
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
/**
* #see https://stackoverflow.com/questions/6991648
* #see https://stackoverflow.com/questions/6887296
* #see https://stackoverflow.com/questions/5797965
*/
public class LinePanel extends JPanel {
private MouseHandler mouseHandler = new MouseHandler();
private Point p1 = new Point(100, 100);
private Point p2 = new Point(540, 380);
private boolean drawing;
public LinePanel() {
this.setPreferredSize(new Dimension(640, 480));
this.addMouseListener(mouseHandler);
this.addMouseMotionListener(mouseHandler);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.blue);
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(8,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
g.drawLine(p1.x, p1.y, p2.x, p2.y);
}
private class MouseHandler extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
drawing = true;
p1 = e.getPoint();
p2 = p1;
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
drawing = false;
p2 = e.getPoint();
repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
if (drawing) {
p2 = e.getPoint();
repaint();
}
}
}
private class ControlPanel extends JPanel {
private static final int DELTA = 10;
public ControlPanel() {
this.add(new MoveButton("\u2190", KeyEvent.VK_LEFT, -DELTA, 0));
this.add(new MoveButton("\u2191", KeyEvent.VK_UP, 0, -DELTA));
this.add(new MoveButton("\u2192", KeyEvent.VK_RIGHT, DELTA, 0));
this.add(new MoveButton("\u2193", KeyEvent.VK_DOWN, 0, DELTA));
}
private class MoveButton extends JButton {
KeyStroke k;
int dx, dy;
public MoveButton(String name, int code,
final int dx, final int dy) {
super(name);
this.k = KeyStroke.getKeyStroke(code, 0);
this.dx = dx;
this.dy = dy;
this.setAction(new AbstractAction(this.getText()) {
#Override
public void actionPerformed(ActionEvent e) {
LinePanel.this.p1.translate(dx, dy);
LinePanel.this.p2.translate(dx, dy);
LinePanel.this.repaint();
}
});
ControlPanel.this.getInputMap(WHEN_IN_FOCUSED_WINDOW)
.put(k, k.toString());
ControlPanel.this.getActionMap()
.put(k.toString(), new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
MoveButton.this.doClick();
}
});
}
}
}
private void display() {
JFrame f = new JFrame("LinePanel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.add(new ControlPanel(), BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new LinePanel().display();
}
});
}
}
Is this going to work like an etch-a-sketch? Then you need to track the current position of the point.
Point current = new Point(0, 0); //for example.
Then when the user clicks the buttons you can simply increment or decrement x and y accordingly.
On left arrow:
current.setX(current.getX() - INC);
where INC could be a variable that specifies the length of the distance to draw the line. Maybe 5? Always set a second point p1 to the previous location though.
It is always easier to create a class that extends Canvas or JPanel to draw on rather than draweing directly on the JFrame.
e.g.
public class Circuit extends JFrame {
Point p1, current;
JPanel drawPanel;
//your other declarations
public Circuit(){
super();
drawPanel = new DrawPanel();
p1 = new Point(0, 0);
current = new Point(0, 0);
add(drawPanel, BorderLayout.CENTER);
//your other code
}
class DrawingPanel extends JPanel{
public void paintComponent(Graphics g){
g.drawLine(p1.getX(), p1.getY(), current.getX(), current.getY());
}
}
//the rest of your code.
}
There is a simple answer for triggering graphics: e.g. The following code can be placed inside a click event and used for drawing a few simple objects on a jPanel. jPanel1 in this case was situated on one side of a tabbed jPanel7 and next to the triggering button. To do this in netbeans GUI, the code was placed inside the button action event. Once the usual errors appeared for not having the proper imports, right click on the code and click on "fix imports". Bingo, all is well :-) Warning: the setBackground command for the panel will override the graphics object. If you set the background color without using the graphics object, you will not see your objects!
Graphics g = jPanel1.getGraphics();
g.setColor(Color.blue);
g.drawLine( 0, 50, 20, 50);
g.setColor(Color.white);
g.fillRect(40, 50, 20, 20);
g.setColor(Color.blue);
g.drawRect(40, 50, 20, 20);
g.drawOval(80, 50, 20, 20);
g.setColor(Color.green);
g.fillOval(80, 50, 18, 18);
This restores your faith in true love :-)
The difficulty here is that any change or repaint will erase your effort. This approach is specifically discouraged by the Java founders. But in the current rendition of Netbeans Swing, where extending the jPanel is made difficult by locking code changes, this approach could be your only short term solution. A simple persistent graphic extension for the jPanel would be a most welcome addition to the current Netbeans Swing environment, a graphics panel. This would allow you to drag and drop the graphics panel and then get on with the event driven use of that panel. 40 other IDE's already have this, it seems Java has been slow to add this feature.
My issues is that I have created a JPanel that draws a gradient as a background. But when I go to add components to it (like a JButton) it does nothing...
Please help!
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Window;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class CocoaTrashBar extends JPanel {
String titleText = "";
Color topLineColor = new Color(128, 128, 128);
Color bottomLineColor = new Color(69, 69, 69);
Color gradientTop = new Color(116, 116, 116);
Color gradientBottom = new Color(81, 81, 81);
public CocoaTrashBar() {
setDefaults();
}
public CocoaTrashBar(String title) {
setDefaults();
this.titleText = title;
}
public void setTitle(String title) {
this.titleText = title;
this.repaint();
}
private void setDefaults() {
super.setOpaque(true);
this.setPreferredSize(new Dimension(0, 24));
installWindowFocusListener(new WindowFocusListener() {
public void windowGainedFocus(WindowEvent e) {
topLineColor = new Color(128, 128, 128);
bottomLineColor = new Color(69, 69, 69);
gradientTop = new Color(116, 116, 116);
gradientBottom = new Color(81, 81, 81);
repaintComponent();
}
public void windowLostFocus(WindowEvent e) {
topLineColor = new Color(171, 171, 171);
bottomLineColor = new Color(103, 103, 103);
gradientTop = new Color(156, 156, 156);
gradientBottom = new Color(121, 121, 121);
repaintComponent();
}
}, this);
}
private static void installWindowFocusListener(
WindowFocusListener focusListener, JComponent component) {
component.addPropertyChangeListener("Frame.active",
createFrameFocusPropertyChangeListener(focusListener, component));
}
private static PropertyChangeListener createFrameFocusPropertyChangeListener(
final WindowFocusListener focusListener, final JComponent component) {
return new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
Window window = SwingUtilities.getWindowAncestor(component);
boolean hasFocus = (Boolean) component.getClientProperty("Frame.active");
if (hasFocus) {
focusListener.windowGainedFocus(
new WindowEvent(window, WindowEvent.WINDOW_GAINED_FOCUS));
} else {
focusListener.windowLostFocus(
new WindowEvent(window, WindowEvent.WINDOW_LOST_FOCUS));
}
}
};
}
private void repaintComponent() {
this.repaint();
}
#Override
public void paint(Graphics g) {
super.paintComponent(g);
Graphics2D g2d =(Graphics2D)g;
// Draw first line
g2d.setPaint(topLineColor);
g2d.drawLine(0, 0, this.getWidth(), 0);
// Draw last line
g2d.setPaint(bottomLineColor);
g2d.drawLine(0, 23, this.getWidth(), 23);
// Draw gradient
GradientPaint gradient = new GradientPaint(
this.getX(),
this.getY()+1,
gradientTop,
this.getX(),
this.getHeight()-1,
gradientBottom);
g2d.setPaint(gradient);
g2d.fillRect(this.getX(), this.getY()+1, this.getWidth(), this.getHeight()-2);
if(titleText != null) {
g2d.setFont(new Font("", Font.BOLD, 13));
g2d.setColor(Color.WHITE);
g2d.drawString(titleText, 10, 16);
}
g.dispose();
}
}
the problem is with your paint method override calling paintComponent
replace your paint method with this:
protected void paintComponent(Graphics g)
{
if (isOpaque())
{
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
}
Graphics2D g2d = (Graphics2D) g;
// Draw first line
g2d.setPaint(topLineColor);
g2d.drawLine(0, 0, this.getWidth(), 0);
// Draw last line
g2d.setPaint(bottomLineColor);
g2d.drawLine(0, 23, this.getWidth(), 23);
// Draw gradient
GradientPaint gradient = new GradientPaint(this.getX(), this.getY() + 1, gradientTop, this.getX(), this.getHeight() - 1, gradientBottom);
g2d.setPaint(gradient);
g2d.fillRect(this.getX(), this.getY() + 1, this.getWidth(), this.getHeight() - 2);
if (titleText != null)
{
g2d.setFont(new Font("", Font.BOLD, 13));
g2d.setColor(Color.WHITE);
g2d.drawString(titleText, 10, 16);
}
}
In method paint(Graphics g), your first line is:
super.paintComponent(g);
This will paint your button. The rest of that method will proceed to paint over that button:
g2d.fillRect(this.getX(), this.getY()+1, this.getWidth(), this.getHeight()-2);
Hence, you see no button. Make that first line the last line and you should be good.