JComboBox covers other things? - java

After clicking on the JComboBox, JComboBox covers up some parts of the painting with grey rectangular shaped thing, is there something wrong with the code and how do I fix it? Thanks!
Here's the image.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.Box;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class MouseButtonTester extends JFrame implements MouseMotionListener{
int x,y,r;
JComboBox colorChooser;
Color color;
JTextField red = new JTextField();
JTextField green = new JTextField();
JTextField blue = new JTextField();
JPanel topPanel = new JPanel();
JComboBox pen;
int fillKind;
Object[] chooseRGB = {
"Red: ", red,
"Green: ", green,
"Blue: ", blue
};
public MouseButtonTester(){
super();
this.addMouseMotionListener(this);
setResizable(true);
setLayout(new BorderLayout());
add(topPanel,BorderLayout.NORTH);
topPanel.setLayout(new GridLayout(1,2));
colorChooser = new JComboBox();
pen = new JComboBox();
topPanel.add(pen);
topPanel.add(colorChooser);
colorChooser.setBackground(Color.WHITE);
pen.setBackground(Color.WHITE);
pen.addItem("Pen");
pen.addItem("Marker");
pen.addItem("Highlighter");
pen.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(pen.getSelectedItem().toString().equals("Pen")){
fillKind = 0;
r = 8;
}else if(pen.getSelectedItem().toString().equals("Marker")){
fillKind = 0;
r = 15;
}else if(pen.getSelectedItem().toString().equals("Highlighter")){
fillKind = 1;
}
}
});
colorChooser.setFont(new Font("Serif",Font.PLAIN,14));
colorChooser.addItem("Red");
colorChooser.addItem("Orange");
colorChooser.addItem("Yellow");
colorChooser.addItem("Green");
colorChooser.addItem("Blue");
colorChooser.addItem("Violet");
colorChooser.addItem("Purple");
colorChooser.addItem("Choose RGB");
colorChooser.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if("Red" == colorChooser.getSelectedItem().toString()){
color = Color.RED;
}else if("Orange" == colorChooser.getSelectedItem().toString()){
color = Color.ORANGE;
}else if("Yellow" == colorChooser.getSelectedItem().toString()){
color = Color.YELLOW;
}
else if("Green" == colorChooser.getSelectedItem().toString()){
color = Color.GREEN;
}
else if("Blue" == colorChooser.getSelectedItem().toString()){
color = Color.BLUE;
}
else if("Violet" == colorChooser.getSelectedItem().toString()){
color = new Color(180,0,200);
}
else if("Purple" == colorChooser.getSelectedItem().toString()){
color = new Color(150,0,200);
}
else if("Purple" == colorChooser.getSelectedItem().toString()){
}
else if("Choose RGB" == colorChooser.getSelectedItem().toString()){
int option = JOptionPane.showConfirmDialog(null, chooseRGB, "Choose RGB", JOptionPane.OK_CANCEL_OPTION);
if(option == JOptionPane.OK_OPTION){
int redValue = Integer.parseInt(red.getText());
int greenValue = Integer.parseInt(green.getText());
int blueValue = Integer.parseInt(blue.getText());
color = new Color(redValue,greenValue,blueValue);
}
}
}
});
}
Graphics graphics;
public void paint(Graphics g){
graphics = g.create();
}
public void mouseDragged(MouseEvent e) {
x = e.getX();
y = e.getY();
graphics.setColor(color);
if(fillKind == 0){
graphics.fillOval(x, y, r, r);
}else if(fillKind == 1){
graphics.fillRect(x, y, 10, 25);
}
repaint();
}
public void mouseMoved(MouseEvent arg0) {
//No actions
}
}

If you look at your code carefully, the JComboBox drawn on JPanel it means drawn on drawing area.Simple way to fix this issue create two panel ; first one for tools (combobox)and add your other tools on, and another panel to drawing area.
Another way is after item choosed repaint your panel.

Related

How I can change the background color of JFrame in this program?

I use the setBackground() method in the Driver Class to change the background color but it does not work.
package paint1;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JPanel;
/**
*
* #author Rehan Shakir
*/
public class PaintPanel extends JPanel {
private final ArrayList<Point> point = new ArrayList<>();
private Color color;
private final JButton red,blue,yellow,green,gray;
private int x = 0;
private int y = 0;
public PaintPanel()
{
setLayout(null);
red = new JButton(" Red ");
red.setBounds(0, 0, 80, 50);
red.setBackground(Color.red);
add(red);
blue = new JButton(" Blue ");
blue.setBounds(82,0 , 80, 50);
blue.setBackground(Color.BLUE);
add(blue);
yellow = new JButton("Yellow");
yellow.setBounds(163,0 , 80, 50);
yellow.setBackground(Color.yellow);
add(yellow);
green = new JButton(" Green");
green.setBounds(242,0 , 80, 50);
green.setBackground(Color.green);
add(green);
gray = new JButton(" Gray ");
gray.setBounds(322,0 , 80, 50);
gray.setBackground(Color.gray);
add(gray);
handler h = new handler();
red.addActionListener(h);
blue.addActionListener(h);
yellow.addActionListener(h);
green.addActionListener(h);
gray.addActionListener(h);
setBackground(Color.RED);
addMouseMotionListener(
new MouseMotionAdapter()
{
#Override
public void mouseDragged(MouseEvent e)
{
x = e.getX();
y = e.getY();
repaint();
}
}
);
}
private class handler implements ActionListener
{
#Override
public void actionPerformed(ActionEvent e)
{
String s = e.getActionCommand();
if(s.equals(" Red "))
color = Color.RED;
else if(s.equals(" Blue "))
color = Color.blue;
else if(s.equals("Yellow"))
color = Color.yellow;
else if(s.equals(" Green"))
color = Color.green;
else if(s.equals(" Gray "))
color = Color.gray;
}
}
#Override
public void paintComponent(Graphics g)
{
g.setColor(color);
g.fillOval(x, y, 20, 5);
}
}
<<>>
Here, I use the setBackground() method to change the color but it does not work.
package paint1;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JLabel;
/**
*
* #author Rehan Shakir
*/
public class Paint1 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
JFrame Jf = new JFrame("A Simple Paint Program");
PaintPanel f = new PaintPanel();
f.setBackground(Color.red); //To Change BACKGROUND COLOR
Jf.add(f,BorderLayout.CENTER);
Jf.add(new JLabel("Drag The Mouse to Draw"),BorderLayout.SOUTH);
Jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Jf.setBackground(Color.black);
Jf.setVisible(true);
Jf.setSize(800,600);
}
}
Please provide me the solution, how can I change the background color of my JFrame? I just want to make the background color of JFrame from the default color to White color.
You've forget to call the parent method in paintComponent.
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g); // add this line to consider background!!!
g.setColor(color);
g.fillOval(x, y, 20, 5);
}
Important: Don't use setBounds() but rather learn the LayoutManager concept. This will help you to make your UI independed to OS, display resolution and window resizing.

Why after using method removeAll or remove(panel), I have to click outside the window and then back in for the rect to move

Hi am new to programming and am trying to make a game with a start menu and then if you click "start" the screen clears and shows a rect in a black background that you can move around the screen with VK up/down/left/right.
But every time i click start i have to click outside of the window and then back the window for the rect to move around
I have tried to use getContentPane to add panel to the window but still every time i click start have to click outside and then back in the window to move the rect.
Help, what do i need to fix/add to not click outside of the frame and the back again to move the rect around
Heres my code the menu screen :
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
public class Menuscreen {
private int WIDTH = 800;
private int HEIGHT = 600;
public void menuscreen () {
//Window
final JFrame window = new JFrame();
window.setVisible(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(WIDTH, HEIGHT);
window.setResizable(false);
window.setLocationRelativeTo(null);
//Panel
final JPanel panel = new JPanel();
panel.setBackground(Color.BLACK);
panel.setVisible(true);
panel.setLayout(null);
window.add(panel);
//Title
JLabel label = new JLabel("SNAKE");
panel.add(label);
label.setBounds(290, 5, 204, 73);
label.setFont(new Font("Tahoma", Font.BOLD, 60));
label.setHorizontalAlignment(SwingConstants.CENTER);
label.setForeground(Color.RED);
label.setBackground(Color.red);
//Buttons
//start button
JButton bstart = new JButton ("Start");
panel.add(bstart);
bstart.setBounds(424, 200, 70, 60);
bstart.setVisible(true);
//start button - run snake on click
bstart.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
window.getContentPane().remove(panel);
snake snake = new snake();
window.add(snake);
window.revalidate();
window.repaint();
}
});
//exit button
JButton bexit = new JButton ("Exit");
panel.add(bexit);
bexit.setBounds(290, 200, 70, 60);
bexit.setVisible(true);
//exit button - close on click
bexit.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
}
}
and the snake class:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Rectangle2D;
import javax.swing.JPanel;
import javax.swing.Timer;
public class snake extends JPanel implements ActionListener, KeyListener {
public void thicks () {}
public snake () {
setBackground(Color.BLACK);
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
//thread = new Thread(this);
// thread.start();
}
private static final long serialVersionUID = 1L;
Timer fps = new Timer( 5, this);
double x =0 , y = 0, speedx = 0, speedy = 0;
public void paintComponent(Graphics g) {
fps.start();
super.paintComponent(g);
g.setColor(Color.blue);
Graphics2D graphics = (Graphics2D) g;
Rectangle2D rect = new Rectangle2D.Double(x, y, 40, 40);
graphics.fill(rect);
}
public void actionPerformed(ActionEvent e) {
if(x < 0 || x > 740 ) {
speedx= -speedx;
}
if(y < 0 || y > 520) {
speedy = -speedy;
}
x += speedx;
y += speedy;
repaint();
}
public void down() {
speedy = 2;
speedx = 0;
}
public void up() {
speedy = -2;
speedx = 0;
}
public void right() {
speedy = 0;
speedx = 2;
}
public void left() {
speedy = 0;
speedx = -2;
}
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_DOWN) {
down();
}
if(keyCode == KeyEvent.VK_UP) {
up();
}
if(keyCode == KeyEvent.VK_RIGHT) {
right();
}
if(keyCode == KeyEvent.VK_LEFT) {
left();
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
public void run() {
}
}
lastly the main
public class Main {
public static void main(String [] args) {
Menuscreen Menuscreen = new Menuscreen();
Menuscreen.menuscreen();
}
}

How to connect my finished java methods with graphics?

I am creating minesweeper game on Java, and have nearly finished all the methods, yet have never worked with graphics before. I would love to apply simple graphics to the methods such as a grid looking board representing the 2D array, and flags and bombs that may replace the characters i am working with now. I am not sure how to add these graphics to my already created methods. For instance, right now, I have an & sign representing bombs and # representing empty boxes.
Here is example how you can work with 2D
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class Dialog extends JFrame {
JPanel panSouth;
JPanel panel;
JButton but;
JTextField tf1;
JTextField tf2;
JTextField tf3;
JTextField tf4;
private int colorIndex = 0;
Color color = Color.BLACK;
public Dialog() {
super("Graphics by Java: the cells drawing");
setSize(700, 700);
try {
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
SwingUtilities.updateComponentTreeUI(this);
} catch (Exception e) {
e.printStackTrace();
}
JFrame.setDefaultLookAndFeelDecorated(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(new BorderLayout());
panSouth = new JPanel() {
#Override
public void paint(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(color);
g2d.setStroke(new BasicStroke(Integer.parseInt(tf4.getText())));
int bx = panSouth.getWidth();
int by = panSouth.getHeight();
int nx = Integer.parseInt(tf1.getText());
int ny = Integer.parseInt(tf2.getText());
int dx = Math.round( bx / nx);
int dy = Math.round( by / ny);
double an = Integer.parseInt(tf3.getText());
g2d.rotate(Math.toRadians(an));
// OX
int fromX;
for (int i = -2*nx; i < nx * 2; i++) {
fromX = i * dx;
g2d.drawLine(fromX, -2*by, fromX, by*2);
}
// OX
int fromY;
for (int i = -2*ny; i < ny * 2; i++) {
fromY = i * dy;
g2d.drawLine(-2*bx, fromY, bx*2, fromY);
}
}
};
panel = new JPanel();
// panel.setBackground(Color.PINK);
// panSouth.setBackground(Color.CYAN);
tf1 = new JTextField(5);
tf1.setText("25");
tf2 = new JTextField(5);
tf2.setText("15");
tf3 = new JTextField(5);
tf3.setText("0");
tf4 = new JTextField(5);
tf4.setText("1");
but = new JButton("Change");
panel.add(new JLabel("T: "));
panel.add(tf4);
panel.add(new JLabel("X: "));
panel.add(tf1);
panel.add(new JLabel("Y: "));
panel.add(tf2);
panel.add(new JLabel(" D: "));
panel.add(tf3);
panel.add(but);
add(panel, BorderLayout.SOUTH);
add(panSouth, BorderLayout.CENTER);
but.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
repaint();
}
});
addMouseListener(new MouseAdapter() {
// #Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
colorIndex = colorIndex + 1;
if (colorIndex > 2) {
colorIndex = 0;
}
switch (colorIndex) {
case 0:
color = Color.RED;
break;
case 1:
color = Color.BLUE;
break;
case 2:
color = Color.GREEN;
break;
default:
color = Color.RED;
break;
}
repaint();
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Dialog().setVisible(true);
}
});
}
}
Here are some buttons and mouse listener where you can use to mark bombs.

How to Make a Splash Screen

I have a program which should has splash screen on JPanel, after button click should show another JPanel (object of the class) and draw shapes. I tried remove splash JPanel and after that add JPanel for drawing but it doeesn't work. How can I fix it? Two JLabel should be in the center of screen and it should be on 2 lines.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JComponent;
/**
*
* #author Taras
*/
public class MyComponent extends JComponent {
int i;
Color randColor;
public MyComponent()
{
this.i = i;
addMouseListener(new MouseHandler());
}
private ArrayList<Rectangle2D> arrOfRect=new ArrayList<>();
private ArrayList<Ellipse2D> arrOfEllipse=new ArrayList<>();
// private ArrayList<Color> randColor = new ArrayList<>();
Random rand = new Random();
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (Rectangle2D r : arrOfRect) {
g.setColor(new Color(rand.nextFloat(), rand.nextFloat(), rand.nextFloat()));
g2.draw(r);
}
for (Ellipse2D e : arrOfEllipse) {
g.setColor(new Color(rand.nextFloat(), rand.nextFloat(), rand.nextFloat()));
g2.draw(e);
}
}
public void add(Point2D p)
{
double x=p.getX();
double y=p.getY();
if (Pole.i == 1){
Ellipse2D ellipse = new Ellipse2D.Double(x, y, 100,100);
//randColor = new Color(randRed(), randGreen(), randBlue());
arrOfEllipse.add(ellipse);
}
if (Pole.i == 2){
Rectangle2D rectangls=new Rectangle2D.Double(x, y, 100, 100);
arrOfRect.add(rectangls);
}
if (Pole.i == 3){
Rectangle2D rectangls=new Rectangle2D.Double(x, y, 150, 100);
arrOfRect.add(rectangls);
}
if (Pole.i == 4){
Ellipse2D ellipse = new Ellipse2D.Double(x, y, 100,50);
arrOfEllipse.add(ellipse);
}
}
private class MouseHandler extends MouseAdapter {
public void mousePressed(MouseEvent event)
{
add(event.getPoint());
//Color rColor = new Color(randRed(), randGreen(), randBlue());
//randColor.add(rColor);
repaint();
}
}
private int randRed() {
int red;
Random randomNumber = new Random();
red = randomNumber.nextInt(255);
return red;
}
private int randGreen() {
int green;
Random randomNumber = new Random();
green = randomNumber.nextInt(255);
return green;
}
private int randBlue() {
int blue;
Random randomNumber = new Random();
blue = randomNumber.nextInt(255);
return blue;
}
}
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import org.omg.CosNaming.NameComponent;
public class Pole extends JFrame {
public static int i;
public static JPanel nameContainer = new JPanel(new GridLayout(2, 1));
public static JFrame frame= new JFrame("Shape Stamper!");
public static void main(String[] args) {
JPanel container;
JButton circle = new JButton("Circle");
JButton square = new JButton("Square");
JButton rectangle = new JButton("Rectangle");
JButton oval = new JButton("Oval");
JLabel programName = new JLabel("Shape Stamper!");
JLabel programmerName = new JLabel("Progrramed by: ");
Font font = new Font("Serif", Font.BOLD, 32);
programName.setFont(font);
font = new Font("Serif", Font.ITALIC, 16);
programmerName.setFont(font);
programName.setHorizontalAlignment(JLabel.CENTER);
programmerName.setHorizontalAlignment(JLabel.CENTER);
//programmerName.setVerticalAlignment(JLabel.CENTER);
// nameContainer.setLayout(new BorderLayout());
nameContainer.add(programName);
nameContainer.add(programmerName);
//nameContainer.setLayout(new BoxLayout(nameContainer, BoxLayout.X_AXIS));
container = new JPanel(new GridLayout(1, 4));
container.add(circle);
container.add(square);
container.add(rectangle);
container.add(oval);
circle.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
i = 1;
frame.remove(nameContainer);
frame.repaint();
System.out.println(i);
}
});
square.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
i = 2;
}
});
rectangle.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
i = 3;
}
});
oval.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
i = 4;
}
});
MyComponent shape = new MyComponent();
frame.setSize(500, 500);
frame.add(shape, BorderLayout.CENTER);
frame.add(container, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Here's an example of making a splash screen using an image.
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.*;
public class CircleSplashScreen {
public CircleSplashScreen() {
JFrame frame = new JFrame();
frame.getContentPane().add(new ImagePanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setUndecorated(true);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setBackground(new Color(0, 0, 0, 0));
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new CircleSplashScreen();
}
});
}
#SuppressWarnings("serial")
public class ImagePanel extends JPanel {
BufferedImage img;
public ImagePanel() {
setOpaque(false);
setLayout(new GridBagLayout());
try {
img = ImageIO.read(new URL("http://www.iconsdb.com/icons/preview/royal-blue/stackoverflow-4-xxl.png"));
} catch (IOException ex) {
Logger.getLogger(CircleSplashScreen.class.getName()).log(Level.SEVERE, null, ex);
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
}
}

Drawing directly on glasspane: not working

I am developing an app using Swing. While user interact with the app, help data may become available in a closed section of the screen, and I'd like to draw a small arrow pointing to that section when this happens.
To do this, I extended a JPanel and added it as the glasspane of the app jframe. The name of the custom glass pane class is AlertGlassPane.
The AlertGlassPane do this: waits until new help data is available. When this happens and the help section is closed, it finds the position of the help section on the screen and then draws an animated arrow at its side.
To draw the arrow I extended the method paintComponent of the glass pane.
To animate the arrow I created a small thread that loop every 100 ms, calling repaint on the glass pane.
The problem: Java ignores my drawing... if a trigger the start of the animation and stand still, nothing happens. No drawing is shown on the app.
I know that the loop is running and paintComponent is being called, but the custom paint is not taking effect.
But if I move the mouse over the region where the arrow should be rendered, it does! But just when the mouse is moving. If a stop move the mouse, the animation stops too, and the arrow freezes on the last position before the mouse stop (or leaves the area).
I tried a lot of things (as set the clip region of the drawing, for example), but nothing seems to work. The only thing that works was when I called by mistake repaint from inside the paintComponent.
At this moment I'm looking for a way to comunicate to the rendering system that a givem region of my glasspane needs to be repainted (repaint(x, y, w, h) didn't work...). Maybe moving the custom rendering to a JLabel and then adding this label to the glasspane? I don't like this approach...
I'll try to clean up the code before post a snippet here. Would it help?
Thanks in advance!
snnipet:
package br.com.r4j.test;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.image.BufferedImage;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.text.JTextComponent;
/**
*
* #author
*/
public class TestGlassPaneAnimation extends JPanel
{
private static TestGlassPaneAnimation gvp = new TestGlassPaneAnimation();
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
JFrame f = new JFrame("Anitest in glass");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//f.setResizable(false);
f.setLayout(new GridLayout(5, 3));
f.add(new JLabel("First Name :"));
f.add(new JTextField(20));
f.add(new JLabel("Last Name :"));
f.add(new JTextField(20));
f.add(new JLabel("Phone Number :"));
f.add(new JTextField(20));
f.add(new JLabel("Email:"));
f.add(new JTextField(20));
f.add(new JLabel("Address :"));
f.add(new JTextField(20));
JButton btnStart = new JButton("Click me, please!");
f.add(btnStart);
btnStart.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
gvp.startAnimation();
}
});
f.setGlassPane(gvp);
f.pack();
f.setVisible(true);
gvp.setVisible(true);
}
});
}
private BufferedImage icon;
private boolean animate = false;
private long timeStart = 0;
private Thread thrLastActive = null;
public TestGlassPaneAnimation()
{
setLayout(null);//this is the exception to the rule case a layoutmanager might make setting Jlabel co-ords harder
setOpaque(false);
Icon icon1 = UIManager.getIcon("OptionPane.warningIcon");
int imgW = icon1.getIconWidth();
int imgH = icon1.getIconHeight();
this.icon = ImageUtilities.getBufferedImageOfIcon(icon1, imgW, imgH);
this.animate = false;
}
public void startAnimation()
{
this.animate = true;
this.timeStart = (new Date()).getTime();
if (this.thrLastActive != null)
this.thrLastActive.interrupt();
this.thrLastActive = new Thread(new Runnable()
{
public void run()
{
try
{
while (true)
{
// int x = 250, y = 250;
// int width = 60, height = 60;
Thread.currentThread().sleep(100);
// frmRoot.invalidate();
// repaint(x, y, width, height);
repaint(new Rectangle(x, y, width, height));
// repaint(new Rectangle(10, 10, 2000, 2000));
// repaint();
// paintComponent(getGraphics());
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
this.thrLastActive.start();
}
protected void paintComponent(Graphics g)
{
try
{
// enables anti-aliasing
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
java.awt.Composite composite = g2.getComposite();
System.err.println("b1: " + g.getClipBounds());
if (this.animate)
{
long timeSpent = (new Date()).getTime() - timeStart;
int x = 10, y = 150;
int width = 60, height = 60;
float maxAlpha = 0.8f;
x += (-100*Math.sin(5*2*Math.PI*timeSpent/10000)+50)/15;
System.err.println("painting::x: " + x + ", y: " + y + ", sin: " + (Math.sin(6*2*Math.PI*timeSpent/10000)));
// g.setClip(x-10, y-10, width, height);
System.err.println("b2: " + g.getClipBounds());
AlphaComposite alpha2 = AlphaComposite.SrcOver.derive(maxAlpha);
g2.setComposite(alpha2);
g2.drawImage(this.icon, x, y, null);
g2.setComposite(composite);
g2.setComposite(composite);
}
}
catch (Throwable e)
{
System.err.println("Errr!");
e.printStackTrace();
}
}
}
class ImageUtilities {
public static BufferedImage resize(BufferedImage image, int width, int height) {
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TRANSLUCENT);
Graphics2D g2d = (Graphics2D) bi.createGraphics();
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.drawImage(image, 0, 0, width, height, null);
g2d.dispose();
return bi;
}
public static BufferedImage getBufferedImageOfIcon(Icon icon, int imgW, int imgH) {
BufferedImage img = new BufferedImage(imgW, imgH, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = (Graphics2D) img.getGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
icon.paintIcon(null, g2d, 0, 0);
g2d.dispose();
return img;
}
}
Hmm not sure exactly whats going on with the snippet you gave but as it looks like it was taken from mine I wrote another example (I had to change a 1 or 2 lines of code in showWarningIcon(Component c) and refreshLocations() methods but nothing major:
If anything except david is typed and the button (click me, please) clicked it will show this:
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class TestGlassPaneAnimation {
private static GlassValidationPane gvp = new GlassValidationPane();
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame f = new JFrame("Anitest in glass");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
//f.setResizable(false);
f.setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
gc.fill = GridBagConstraints.HORIZONTAL;
gc.weightx = 1;
gc.weighty = 1;
gc.insets = new Insets(15, 15, 15, 15);//give some space so icon doesnt cover components when shown
gc.gridx = 0;
gc.gridy = 0;
f.add(new JLabel("First Name:"), gc);
final JTextField jtf = new JTextField(20);
gc.gridx = 1;
f.add(jtf, gc);
gc.gridx = 0;
gc.gridy = 1;
f.add(new JLabel("Surname:"), gc);
final JTextField jtf2 = new JTextField(20);
gc.gridx = 1;
f.add(jtf2, gc);
JButton btnStart = new JButton("Click me, please!");
gc.gridx = 2;
f.add(btnStart, gc);
btnStart.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (!jtf.getText().equalsIgnoreCase("david")) {
gvp.showWarningIcon(jtf);
}
}
});
f.addComponentListener(new ComponentAdapter() {//so wjen frame is resized icons follow
#Override
public void componentResized(ComponentEvent ce) {
super.componentResized(ce);
gvp.refreshLocations();
}
});
f.setGlassPane(gvp);
f.pack();
f.setVisible(true);
gvp.setVisible(true);
}
});
}
}
class GlassValidationPane extends JPanel {
private HashMap<Component, JLabel> warningLabels = new HashMap<>();
private ImageIcon warningIcon;
public GlassValidationPane() {
setLayout(null);//this is the exception to the rule case a layoutmanager might make setting Jlabel co-ords harder
setOpaque(false);
Icon icon = UIManager.getIcon("OptionPane.warningIcon");
int imgW = icon.getIconWidth();
int imgH = icon.getIconHeight();
BufferedImage img = ImageUtilities.getBufferedImageOfIcon(icon, imgW, imgH);
warningIcon = new ImageIcon(ImageUtilities.resize(img, 24, 24));
}
void showWarningIcon(Component c) {
if (warningLabels.containsKey(c)) {
return;
}
JLabel label = new JLabel();
label.setIcon(warningIcon);
//int x=c.getX();//this will make it insode the component
int x = c.getX() - warningIcon.getIconWidth();//this makes it appear outside/next to component if space
int y = c.getY();
label.setBounds(x, y, warningIcon.getIconWidth(), warningIcon.getIconHeight());
add(label);
revalidate();
repaint();
warningLabels.put(c, label);
}
public void removeWarningIcon(Component c) {
for (Map.Entry<Component, JLabel> entry : warningLabels.entrySet()) {
Component component = entry.getKey();
JLabel jLabel = entry.getValue();
if (component == c) {
remove(jLabel);
revalidate();
repaint();
break;
}
}
warningLabels.remove(c);
}
public void refreshLocations() {
for (Map.Entry<Component, JLabel> entry : warningLabels.entrySet()) {
Component c = entry.getKey();
JLabel label = entry.getValue();
//int x=c.getX();//this will make it insode the component
int x = c.getX() - label.getIcon().getIconWidth();//this makes it appear outside/next to component
int y = c.getY();
label.setBounds(x, y, label.getIcon().getIconWidth(), label.getIcon().getIconHeight());
revalidate();
repaint();
}
}
}
class ImageUtilities {
public static BufferedImage resize(BufferedImage image, int width, int height) {
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TRANSLUCENT);
Graphics2D g2d = (Graphics2D) bi.createGraphics();
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.drawImage(image, 0, 0, width, height, null);
g2d.dispose();
return bi;
}
public static BufferedImage getBufferedImageOfIcon(Icon icon, int imgW, int imgH) {
BufferedImage img = new BufferedImage(imgW, imgH, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = (Graphics2D) img.getGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
icon.paintIcon(null, g2d, 0, 0);
g2d.dispose();
return img;
}
}
If you are looking for a more mature library have a look at JXLayer - Validation Overlays and Validation overlays using glass pane.
Also might want to have a read here which shows many ways of validating a textfields data (other than button press) like DocumentFilter and InputVerifier etc.

Categories

Resources