mouse Clicked event change colors - java

Well the goal of this program is to create a bullseye; and when you click on the panel, it will change the color of the bullseye from red to blue. When you click on mine nothing happens. What is causing this?
import java.awt.*;
public class TargetLogoPanel extends javax.swing.JPanel {
public Color ringColor = Color.RED;
public int size = 400;
public TargetLogoPanel() {
setBackground(Color.WHITE);
setPreferredSize(new Dimension(700,400 ));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
int radius = getHeight();
g.setColor(ringColor);
g.fillOval(
(int)((width/2 ) - (radius * 0.3)),
(int)((height/2) - (radius * 0.3)),
(int)(radius * .6),
(int)(radius * .6));
g.setColor(Color.WHITE);
g.fillOval(
(int)((width / 2) - (radius * 0.22)),
(int)((height / 2) - (radius * 0.22)),
(int)(radius * 0.44),
(int)(radius * 0.44));
g.setColor(ringColor);
g.fillOval(
(int)((width / 2) - (radius * 0.15)),
(int)((height / 2) - (radius * 0.15)),
(int)(radius * 0.3),
(int)(radius * 0.3));
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
formMouseClicked(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
}// </editor-fold>
private void formMouseClicked(java.awt.event.MouseEvent evt) {
if(ringColor == Color.RED){
ringColor = Color.BLUE;
repaint();
} else{
ringColor = Color.RED;
repaint();
}
}
// Variables declaration - do not modify
// End of variables declaration
}

Invoke initComponents() in your panel's constructor.
public TargetLogoPanel() {
initComponents();
setBackground(Color.WHITE);
setPreferredSize(new Dimension(700, 400));
}
As tested:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.JFrame;
/**
* #see http://stackoverflow.com/a/22548923/230513
*/
public class Test {
private void display() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new TargetLogoPanel());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
class TargetLogoPanel extends javax.swing.JPanel {
public Color ringColor = Color.RED;
public int size = 400;
public TargetLogoPanel() {
initComponents();
setBackground(Color.WHITE);
setPreferredSize(new Dimension(700, 400));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
int radius = getHeight();
g.setColor(ringColor);
g.fillOval(
(int) ((width / 2) - (radius * 0.3)),
(int) ((height / 2) - (radius * 0.3)),
(int) (radius * .6),
(int) (radius * .6));
g.setColor(Color.WHITE);
g.fillOval(
(int) ((width / 2) - (radius * 0.22)),
(int) ((height / 2) - (radius * 0.22)),
(int) (radius * 0.44),
(int) (radius * 0.44));
g.setColor(ringColor);
g.fillOval(
(int) ((width / 2) - (radius * 0.15)),
(int) ((height / 2) - (radius * 0.15)),
(int) (radius * 0.3),
(int) (radius * 0.3));
}
/**
* This method is called from within the constructor to initialize the
* form. WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
formMouseClicked(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
}// </editor-fold>
private void formMouseClicked(java.awt.event.MouseEvent evt) {
if (ringColor == Color.RED) {
ringColor = Color.BLUE;
repaint();
} else {
ringColor = Color.RED;
repaint();
}
}
// Variables declaration - do not modify
// End of variables declaration
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Test().display();
}
});
}
}

Essentially, you haven't registered a MouseListener to respond to mouse events.
The initComponents method that the Netbeans form editor created was used to register a MouseListener, but you stopped calling it.
Try calling initComponents within you component's constructor...

Related

How to fix chess board squares not moving to middle

at the moment I try to make a chessboard with fix sizes. I successfully make that the chessboard will be painted in the corner (coordinate 0,0,400,400). However, now I want that the chessboard will always be in the middle also if I move the window.
The background of the chessboard moves always and is always in the middle but the squares are fixed.
To make you understand my problem, I upload some pics where you can see my main issue.
First Start:
Moving the window to the left
Background in the middle but without the white squares
JPanel
import java.awt.Color;
import java.awt.Graphics;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* #author Serge Junk
*/
public class DrawPanel extends javax.swing.JPanel {
/**
* Creates new form DrawPanel
*/
public DrawPanel() {
initComponents();
}
#Override
public void paintComponent(Graphics g)
{
int width = (getWidth() - 400)/2;
int height = (getHeight()- 400)/2;
g.setColor(Color.white);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.gray);
g.fillRect(width, height, 400, 400);
g.setColor(Color.black);
g.drawRect(width, height, 400, 400);
for(int i=width;i<400;i+=100)
{
for(int j=height;j<400;j+=100)
{
g.setColor(Color.white);
g.fillRect(i, j, 50, 50);
g.setColor(Color.black);
g.drawRect(i, j, 50, 50);
}
}
for(int i=width+50;i<400;i+=100)
{
for(int j=height+50;j<400;j+=100)
{
g.setColor(Color.white);
g.fillRect(i, j, 50, 50);
g.setColor(Color.black);
g.drawRect(i, j, 50, 50);
}
}
}
/**
*
*/
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
}// </editor-fold>
// Variables declaration - do not modify
// End of variables declaration
}
JFrame
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* #author Serge Junk
*/
public class MainFrame extends javax.swing.JFrame {
/**
* Creates new form MainFrame
*/
public MainFrame() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
drawPanel1 = new DrawPanel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
javax.swing.GroupLayout drawPanel1Layout = new javax.swing.GroupLayout(drawPanel1);
drawPanel1.setLayout(drawPanel1Layout);
drawPanel1Layout.setHorizontalGroup(
drawPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 652, Short.MAX_VALUE)
);
drawPanel1Layout.setVerticalGroup(
drawPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 473, Short.MAX_VALUE)
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(drawPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(drawPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
pack();
}// </editor-fold>
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MainFrame().setVisible(true);
}
});
}
// Variables declaration - do not modify
private DrawPanel drawPanel1;
// End of variables declaration
}
Here is the "correct" way to draw your squares.
for (int i = width; i < 400 + width; i += 100) {
for (int j = height; j < 400 + height; j += 100) {
g.setColor(Color.white);
g.fillRect(i, j, 50, 50);
g.setColor(Color.black);
g.drawRect(i, j, 50, 50);
}
}
for (int i = width + 50; i < 400 + width; i += 100) {
for (int j = height + 50; j < 400 + height; j += 100) {
g.setColor(Color.white);
g.fillRect(i, j, 50, 50);
g.setColor(Color.black);
g.drawRect(i, j, 50, 50);
}
}
You can achieve it with a twice smaller code:
for (int i = width; i < 400 + width; i += 100) {
for (int j = height; j < 400 + height; j += 100) {
g.setColor(Color.white);
g.fillRect(i, j, 50, 50);
g.fillRect(i+50, j+50, 50, 50);
g.setColor(Color.black);
g.drawRect(i, j, 50, 50);
g.drawRect(i+50, j+50, 50, 50);
}
}

How to fix paint on existing draw

I have some problems with my DrawPanel. I want to make a grill—that should be drawn with the parameters—given by the user by defining the rows and colons.
For example, I enter 3 rows and 5 colons (:), Swing should draw it. The main problem is if I enter the numbers in the TextField and press the draw button, Swing draws the new grill over the old one. Furthermore, sometimes the program doesn't complete some rows or colons and I don't understand why. I already add some numbers such as rows-6 because swing draw a few pixels more than he should. Probably you know a solution for this problem too.
On the picture you can see the lines that are to much. I use a blue line to show how far the lines should go.
DrawPanel (JPanel)
import java.awt.Graphics;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* #author Serge Junk
*/
public class DrawPanel extends javax.swing.JPanel {
/**
* Creates new form DrawPanel
*
*/
private int rows = 1;
private int cols = 2;
public DrawPanel() {
initComponents();
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
// draw the rows
int rowHt = (height / rows)-1;
for (int i = 0; i <= rows; i++){
g.drawLine(0, i * rowHt, width, i * rowHt);
}
// draw the columns
int rowWid = (width / cols)-1;
for (int i = 0; i <= cols; i++){
g.drawLine(i * rowWid, 0, i * rowWid, height);
}
}
public void setRows(int pRows){
rows = pRows;
}
public void setCols(int pCols){
cols = pCols;
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
setPreferredSize(new java.awt.Dimension(300, 200));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
}// </editor-fold>
// Variables declaration - do not modify
// End of variables declaration
}
MainFrame (JFrame)
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* #author Serge Junk
*/
public class MainFrame extends javax.swing.JFrame {
/**
* Creates new form MainFrame
*/
public MainFrame() {
initComponents();
}
public void updateView()
{
drawPanel1.repaint();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
drawPanel1 = new DrawPanel();
jLabel1 = new javax.swing.JLabel();
rowTextField = new javax.swing.JTextField();
jLabel2 = new javax.swing.JLabel();
colsTextField = new javax.swing.JTextField();
drawButton = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
javax.swing.GroupLayout drawPanel1Layout = new javax.swing.GroupLayout(drawPanel1);
drawPanel1.setLayout(drawPanel1Layout);
drawPanel1Layout.setHorizontalGroup(
drawPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 600, Short.MAX_VALUE)
);
drawPanel1Layout.setVerticalGroup(
drawPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 200, Short.MAX_VALUE)
);
jLabel1.setText("Lignes");
jLabel2.setText("Colonnes");
drawButton.setText("Draw");
drawButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
drawButtonActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel1)
.addGap(18, 18, 18)
.addComponent(rowTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 95, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jLabel2)
.addGap(18, 18, 18)
.addComponent(colsTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 95, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(25, 25, 25)
.addComponent(drawButton))
.addGroup(layout.createSequentialGroup()
.addGap(28, 28, 28)
.addComponent(drawPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 600, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap(26, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(41, 41, 41)
.addComponent(drawPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 14, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
.addComponent(rowTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel2)
.addComponent(colsTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(drawButton)))
.addContainerGap())
);
pack();
}// </editor-fold>
private void drawButtonActionPerformed(java.awt.event.ActionEvent evt) {
//E
int row = Integer.valueOf(rowTextField.getText());
int col = Integer.valueOf(colsTextField.getText());
//T
drawPanel1.setRows(row);
drawPanel1.setCols(col);
//S
updateView();
}
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MainFrame().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JTextField colsTextField;
private javax.swing.JButton drawButton;
private DrawPanel drawPanel1;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JTextField rowTextField;
// End of variables declaration
}
Netbeans draw the new grill over the old one.
The first statement in the paintComponent() method should be:
super.paintComponent(g);
This will clear the background before you do your custom painting.
drawPanel1.setRows(row);
drawPanel1.setCols(col);
//S
updateView();
There is no need for the updateView() method. Instead both the setRows(...) and setCols(...) method should invoke repaint() directly. That is it is the responsibility of the component to repaint itself when a property of the component is changed.
sometimes the program doesn't complete some rows or colons and I don't understand why.
int rowHt = height / rows-1;
Be explicit when using formulas so we know exactly what you intend instead of relying in the compiler. So you should use:
int rowHt = (height / rows) - 1;
Don't be afraid to create variables for your parameters:
//g.drawLine(i * rowWid, 0, i * rowWid, height-5);
int xOffset = i * rowWidth;
int yEnd = height - 5;
g.drawLine(xOffset, 0, xOffset, yEnd);
This then allows you to add debug code easily to see exactly what values a being used to draw the line:
System.out.println(xOffset + " : " + yEnd);
Now you should be able to determine if your logic is correct.
So, as camickr suggested, you should not add any hidden variables to the division or rows / height or cols / width, because this is a maintenance nightmare. Stay away from magic values!
The DrawPanel.paintComponent must do a few things.
Don't forget to call super() !
You will need to determine line thickness so you know how much to offset.
Keep your units as floating-point values until you NEED to set them as integers.
Dispose afterwards.
Moreover, you do not want to set instance variables in their declaration, but through a constructor of some sorts.
Additionally, I added two more fields to control line width and color as seen below. I also redesigned the layout so that it is actually legible from a code maintenance standpoint.
Runner
package question58310987;
import javax.swing.*;
public class Runner {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new MainFrame();
setLookAndFeel(frame);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
private static void setLookAndFeel(JFrame frame) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.updateComponentTreeUI(frame);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
}
DrawPanel
package question58310987;
import java.awt.*;
import javax.swing.JPanel;
public class DrawPanel extends JPanel {
private static final long serialVersionUID = 1889951852010548809L;
private int rows;
private int cols;
private int thickness;
private Color fgColor;
private Color bgColor;
private boolean dirty;
private Stroke strokeRef;
public DrawPanel() {
this(3, 3);
}
public DrawPanel(int rows, int cols) {
this(rows, cols, 1, Color.BLACK, null);
}
public DrawPanel(int rows, int cols, int thickness, Color fgColor, Color bgColor) {
super();
this.rows = rows;
this.cols = cols;
this.thickness = thickness;
this.fgColor = fgColor;
this.bgColor = bgColor;
this.dirty = true; // initialized as true
}
private float getStrokeThickness(Graphics2D g2d) {
Stroke stroke = g2d.getStroke();
if (stroke instanceof BasicStroke) {
return ((BasicStroke) stroke).getLineWidth();
}
return 1.0f;
}
/**
* Re-evaluates the state of the properties.
*/
protected void commitProperties(Graphics2D g2d) {
if (dirty) {
strokeRef = new BasicStroke(this.thickness);
dirty = false;
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
commitProperties(g2d);
g2d.setStroke(strokeRef);
float lineSize = getStrokeThickness(g2d); // Calculate line thickness
float halfStroke = lineSize > 2.0f ? lineSize / 2.0f : 1.0f;
int width = this.getWidth();
int height = this.getHeight();
int maxWidth = (int) (width - halfStroke);
int maxHeight = (int) (height - halfStroke);
float yOffset = (((float) maxHeight - halfStroke) / (rows));
float xOffset = (((float) maxWidth - halfStroke) / (cols));
if (bgColor != null) {
g2d.setColor(bgColor);
g2d.fillRect(0, 0, getWidth(), getHeight());
}
g2d.setColor(fgColor);
// Draw the horizontal lines
for (int row = 0; row < rows; row++) {
int y = (int) (row * yOffset + halfStroke);
g2d.drawLine((int) halfStroke, y, maxWidth, y);
}
g2d.drawLine((int) halfStroke, maxHeight, maxWidth, maxHeight); // Draw the final horizontal line
// Draw the vertical lines
for (int col = 0; col < cols; col++) {
int x = (int) (col * xOffset + halfStroke);
g2d.drawLine(x, (int) halfStroke, x, maxHeight);
}
g2d.drawLine(maxWidth, (int) halfStroke, maxWidth, maxHeight); // Draw the final vertical line
g2d.dispose(); // Clear changes
}
public String getFgColorHex() {
return String.format("#%02X%02X%02X", fgColor.getRed(), fgColor.getGreen(), fgColor.getBlue());
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public int getCols() {
return cols;
}
public void setCols(int cols) {
this.cols = cols;
}
public int getThickness() {
return thickness;
}
public void setThickness(int thickness) {
this.thickness = thickness;
this.dirty = true;
}
public Color getFgColor() {
return fgColor;
}
public void setFgColor(Color fgColor) {
this.fgColor = fgColor;
}
public Color getBgColor() {
return bgColor;
}
public void setBgColor(Color bgColor) {
this.bgColor = bgColor;
}
}
MainFrame
package question58310987;
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class MainFrame extends JFrame {
private static final long serialVersionUID = -2796976952328960949L;
private static final String DEFAULT_APP_TITLE = "Main Frame";
private DrawPanel drawPanel;
private JLabel rowLabel;
private JTextField rowTextField;
private JLabel colLabel;
private JTextField colTextField;
private JLabel thicknessLabel;
private JTextField thicknessTextField;
private JLabel colorLabel;
private JTextField colorTextField;
private JButton drawButton;
public MainFrame() {
this(DEFAULT_APP_TITLE);
}
public MainFrame(String title) {
super(title);
initialize();
addChildren();
}
protected void initialize() {
drawPanel = new DrawPanel();
drawPanel.setThickness(6);
drawPanel.setFgColor(Color.BLUE);
drawPanel.setPreferredSize(new Dimension(600, 200));
rowLabel = new JLabel("Rows");
rowTextField = new JTextField(Integer.toString(drawPanel.getRows()), 3);
colLabel = new JLabel("Columns");
colTextField = new JTextField(Integer.toString(drawPanel.getCols()), 3);
thicknessLabel = new JLabel("Thickness");
thicknessTextField = new JTextField(Integer.toString(drawPanel.getThickness()), 3);
colorLabel = new JLabel("Color");
colorTextField = new JTextField(drawPanel.getFgColorHex(), 6);
drawButton = new JButton("Draw");
drawButton.addActionListener(evt -> drawButtonActionPerformed(evt));
}
protected void addChildren() {
GridBagLayout verticalLayout = new GridBagLayout();
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(16, 16, 16, 16); // top, left, bottom, right
getContentPane().setLayout(verticalLayout);
getContentPane().add(drawPanel, gbc);
FlowLayout horizontalLayout = new FlowLayout();
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(horizontalLayout);
buttonPanel.add(rowLabel);
buttonPanel.add(rowTextField);
buttonPanel.add(Box.createHorizontalStrut(30));
buttonPanel.add(colLabel);
buttonPanel.add(colTextField);
buttonPanel.add(Box.createHorizontalStrut(30));
buttonPanel.add(thicknessLabel);
buttonPanel.add(thicknessTextField);
buttonPanel.add(Box.createHorizontalStrut(30));
buttonPanel.add(colorLabel);
buttonPanel.add(colorTextField);
buttonPanel.add(Box.createHorizontalStrut(30));
buttonPanel.add(drawButton);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.insets = new Insets(0, 16, 16, 16); // top, left, bottom, right
getContentPane().add(buttonPanel, gbc);
}
private void drawButtonActionPerformed(ActionEvent evt) {
int row = Integer.valueOf(rowTextField.getText().trim());
int col = Integer.valueOf(colTextField.getText().trim());
int thickness = Integer.valueOf(thicknessTextField.getText().trim());
String colorHex = colorTextField.getText().trim();
drawPanel.setRows(row);
drawPanel.setCols(col);
drawPanel.setThickness(thickness);
drawPanel.setFgColor(hexToColor(colorHex));
this.updateView();
}
public void updateView() {
drawPanel.repaint();
}
/**
* Supports both #FF0000 and #F00 formats.
*
* #param hex a hexadecimal color value from #000000 -> #FFFFFF
* #return
*/
public static final Color hexToColor(String hex) {
if (hex.startsWith("#")) {
hex = hex.replace("#", "");
}
if (hex.length() == 3) {
hex = splicePad(hex, 2);
}
int v = Integer.parseInt(hex, 16);
int r = (v & 0xFF0000) >> 16;
int g = (v & 0xFF00) >> 8;
int b = (v & 0xFF);
return new Color(r, g, b);
}
/**
* Splices each character after itself n-number of times.
*/
public static final String splicePad(String str, final int repeat) {
StringBuffer buff = new StringBuffer();
for (char ch : str.toCharArray()) {
for (int i = 0; i < repeat; i++) {
buff.append(ch);
}
}
return buff.toString();
}
}

Line drawn by Graphics type variable disappears when making a label for it

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.*;
public class NewJFrame extends JFrame {
private Graphics g1;
private JLabel label = new JLabel();
// holds information of all businesses
private Object[][] busInfo = new Object[10][15];
public NewJFrame() {
initComponents();
g1 = jPanel1.getGraphics();
}
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jPanel1 = new javax.swing.JPanel();
jButton1 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 858, Short.MAX_VALUE));
jPanel1Layout.setVerticalGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 564, Short.MAX_VALUE));
jButton1.setText("Click Me");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(
javax.swing.GroupLayout.Alignment.TRAILING,
layout.createSequentialGroup().addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jButton1).addGap(425, 425, 425))
.addGroup(layout.createSequentialGroup().addGap(48, 48, 48)
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(61, Short.MAX_VALUE)));
layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup().addGap(28, 28, 28)
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED).addComponent(jButton1)));
pack();
}// </editor-fold>
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
printBarChart(2, 1);
System.out.println(getSize());
}
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
java.awt.EventQueue.invokeLater(() -> {
new NewJFrame().setVisible(true);
});
}
public void printBarChart(int bestBus, int worstBus) {
busInfo[0][7] = 24325.08;
busInfo[1][7] = 15394.59;
busInfo[2][7] = 186719.84;
int y = jPanel1.getSize().height;
int x = jPanel1.getSize().width;
double balance, maxScale = (double) busInfo[bestBus][7] + 650;
int sameBusDistance, diffBusDistance = 0, scaleNum, maxPoint;
for (int i = 0; i <= 2; ++i) {
if (i == 0) {
diffBusDistance = 0;
} else {
diffBusDistance += 65;
}
// color of best business
if (i == bestBus) {
g1.setColor(Color.YELLOW);
// color of worst business
} else if (i == worstBus) {
g1.setColor(Color.RED);
// color of other businesses (neither best nor worst)
} else {
g1.setColor(Color.BLACK);
}
balance = (double) busInfo[i][7];
sameBusDistance = 25;
scaleNum = y - 100;
maxPoint = scaleNum - (scaleNum * (int) balance / (int) maxScale) + 50;
g1.drawLine(125 + diffBusDistance, y - 50, 125 + diffBusDistance, maxPoint);
g1.drawLine(125 + sameBusDistance + diffBusDistance, y - 50, 125 + sameBusDistance + diffBusDistance,
maxPoint);
g1.drawLine(125 + sameBusDistance + diffBusDistance, maxPoint, 125 + diffBusDistance, maxPoint);
jPanel1.add(label);
jPanel1.setLayout(null);
label.setSize(100, 50);
label.setFont(label.getFont().deriveFont(8f));
label.setLocation(125 + sameBusDistance + diffBusDistance - 30, maxPoint - 50);
label.setText("" + busInfo[i][7]);
}
}
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JPanel jPanel1;
// End of variables declaration
}
Line drawn by Graphics type variable disappears when making a label for it
This code is in a for loop for the number of businesses. I will attach a picture of the problem.The first bar works just fine:
The second however removes the first bar and its label from view:
Printing labels for Bar Charts causing other bars and their labels to dissapear
Again, I suggest that you don't use getGraphics() called on a component. By now you should have minimized and restored your GUI to see that the drawing is not stable when you minimize and restore the GUI. I suggest that you draw in the paintComponent of your JPanel.
There is an exception however -- if you draw in a BufferedImage, you can use a Graphics object obtained from it, and then display the image in an ImageIcon in a JLabel. For example in the code below I create a JLabel filled with an empty image (to give it size). I then fill the image with some bar chart data on button press, put the image into an ImageIcon and then set the JLabel with that icon by calling setIcon(...) on it:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import javax.swing.*;
#SuppressWarnings("serial")
public class DrawInImage extends JPanel {
private static final int IMG_W = 900;
private static final int IMG_H = 700;
private static final int GAP = 20;
private BufferedImage img = new BufferedImage(IMG_W, IMG_H, BufferedImage.TYPE_INT_ARGB);
private Icon icon = new ImageIcon(img);
private JLabel label = new JLabel(icon);
private int[] data = { 4, 2, 9, 7, 3, 8, 2, 8 };
public DrawInImage() {
JPanel btnPanel = new JPanel();
btnPanel.add(new JButton(new AbstractAction("Press Me") {
#Override
public void actionPerformed(ActionEvent arg0) {
printBarChart();
}
}));
setLayout(new BorderLayout());
add(label);
add(btnPanel, BorderLayout.PAGE_END);
}
private void printBarChart() {
// create new image
img = new BufferedImage(IMG_W, IMG_H, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics(); // get image's graphics
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 18));
// get sizes of drawing area
int totalWidth = IMG_W - 2 * GAP;
int totalHeight = IMG_H - 2 * GAP;
// number of columns including gaps
int columns = 2 * data.length + 1;
// calc the max data + 1
int maxData = 0;
for (int i : data) {
if (i > maxData) {
maxData = i;
}
}
maxData++; // + 1
for (int i = 0; i < data.length; i++) {
int x1 = GAP + ((2 * i + 1) * totalWidth) / columns;
int x2 = GAP + ((2 * i + 2) * totalWidth) / columns;
int y1 = GAP + (totalHeight * (maxData - data[i])) / maxData;
int y2 = GAP + totalHeight;
float hue = (float) i / (float) data.length;
Color c = Color.getHSBColor(hue, 1f, 1f);
g2.setColor(c);
g2.fillRect(x1, y1, x2 - x1, y2 - y1);
g2.setColor(Color.BLACK);
String text = "Data " + (i + 1);
int strX = x1;
int strY = y1 - GAP / 2;
g2.drawString(text, strX, strY);
}
g2.dispose(); // dispose of graphics objects *we* create
icon = new ImageIcon(img); // create new icon
label.setIcon(icon); // display in label
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Draw In Image");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new DrawInImage());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
Which displays as

Making two objects rotate at the same time

So I have this assignment where I have to make two objects move at the same time. I know that I should use thread class but i am not sure how to do it. My project has two files. The first one has main method and implements fan object.Here it is:
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
public class DrawArcs extends JFrame {
public DrawArcs() {
setTitle("DrawArcs");
add(new ArcsPanel());
}
/** Main method */
public static void main(String[] args) {
DrawArcs frame = new DrawArcs();
frame.setLocationRelativeTo(null); // Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setVisible(true);
frame.add(new StillClock());
}
}
class ArcsPanel extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int xCenter = getWidth() / 2;
int yCenter = getHeight() / 2;
int radius = (int)(Math.min(getWidth(), getHeight()) * 0.4);
int x = xCenter - radius;
int y = yCenter - radius;
g.fillArc(x, y, 2 * radius, 2 * radius, 0, 30);
g.fillArc(x, y, 2 * radius, 2 * radius, 90, 30);
g.fillArc(x, y, 2 * radius, 2 * radius, 180, 30);
g.fillArc(x, y, 2 * radius, 2 * radius, 270, 30);
}
}
My second file includes implementation of the clock class.
public class StillClock extends JPanel {
private int hour;
private int minute;
private int second;
public StillClock() {
setCurrentTime();
}
public StillClock(int hour, int minute, int second) {
this.hour = hour;
this.minute = minute;
this.second = second;
}
////there are setters and getters here
.
.
.
////
#Override /** Draw the clock */
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// Initialize clock parameters
int clockRadius =
(int)(Math.min(getWidth(), getHeight()) * 0.8 * 0.5);
int xCenter = getWidth() / 2;
int yCenter = getHeight() / 2;
// Draw circle
g.setColor(Color.black);
g.drawOval(xCenter - clockRadius, yCenter - clockRadius,
2 * clockRadius, 2 * clockRadius);
g.drawString("12", xCenter - 5, yCenter - clockRadius + 12);
g.drawString("9", xCenter - clockRadius + 3, yCenter + 5);
g.drawString("3", xCenter + clockRadius - 10, yCenter + 3);
g.drawString("6", xCenter - 3, yCenter + clockRadius - 3);
// Draw second hand
int sLength = (int)(clockRadius * 0.8);
int xSecond = (int)(xCenter + sLength *
Math.sin(second * (2 * Math.PI / 60)));
int ySecond = (int)(yCenter - sLength *
Math.cos(second * (2 * Math.PI / 60)));
g.setColor(Color.red);
g.drawLine(xCenter, yCenter, xSecond, ySecond);
// Draw minute hand
int mLength = (int)(clockRadius * 0.65);
int xMinute = (int)(xCenter + mLength *
Math.sin(minute * (2 * Math.PI / 60)));
int yMinute = (int)(yCenter - mLength *
Math.cos(minute * (2 * Math.PI / 60)));
g.setColor(Color.blue);
g.drawLine(xCenter, yCenter, xMinute, yMinute);
// Draw hour hand
int hLength = (int)(clockRadius * 0.5);
int xHour = (int)(xCenter + hLength *
Math.sin((hour % 12 + minute / 60.0) * (2 * Math.PI / 12)));
int yHour = (int)(yCenter - hLength *
Math.cos((hour % 12 + minute / 60.0) * (2 * Math.PI / 12)));
g.setColor(Color.green);
g.drawLine(xCenter, yCenter, xHour, yHour);
}
public void setCurrentTime() {
// Construct a calendar for the current date and time
Calendar calendar = new GregorianCalendar();
// Set current hour, minute and second
this.hour = calendar.get(Calendar.HOUR_OF_DAY);
this.minute = calendar.get(Calendar.MINUTE);
this.second = calendar.get(Calendar.SECOND);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
So my question is how do I make both fan and clock rotate at the same time?
Here is how it looks the you run the codeenter image description here
So, you're actually asking two questions:
How to animate a number of objects
How to rotate a object (as the clock doesn't need to be rotated)
Rotating
Rotating is relatively easy in 2D Graphics, with a number of possible options. I'm going to use a AffineTransform as a personal preference.
We need to add a couple of things to the ArcsPanel, we need a angle, which represents the current angle of rotation, and a delta, which represents the amount of movement on each animation pass...
public static class ArcsPanel extends JPanel {
protected static final float DELTA = 1.0f;
private float angle = 0;
With this information, we can simply modify the paintComponent method to support the angle property and apply the AffineTransform
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int xCenter = getWidth() / 2;
int yCenter = getHeight() / 2;
int radius = (int) (Math.min(getWidth(), getHeight()) * 0.4);
g2d.setTransform(AffineTransform.getRotateInstance(Math.toRadians(angle), xCenter, yCenter));
int x = xCenter - radius;
int y = yCenter - radius;
g2d.fillArc(x, y, 2 * radius, 2 * radius, 0, 30);
g2d.fillArc(x, y, 2 * radius, 2 * radius, 90, 30);
g2d.fillArc(x, y, 2 * radius, 2 * radius, 180, 30);
g2d.fillArc(x, y, 2 * radius, 2 * radius, 270, 30);
g2d.dispose();
}
Animating a number of objects
Despite what you might think, you don't want more threads, you actually only want one. This one thread will notify all the objects you want to be updated that they should update their animatable states. This thread doesn't care "how" they do that, it only drives the process. Equally, your objects don't care "how" the engine works, only that it will notify them on a regular bases.
Now, Swing is both single threaded and not thread safe. This raises a number of issues when dealing with threads. You can't run long running or blocking operations within the context of the Event Dispatching Thread and you shouldn't update the state of the UI from outside the EDT either.
For simplicity, a Swing Timer is a perfect choice, as it waits off the EDT, but triggers it's updates in the EDT.
First, we need some way for the engine to tell other objects that they should update themselves. Sure you can simply maintain a direct reference to the other components, but this both increases the coupling between objects, it also limits the engines re-usability.
Instead, we define a simple interface...
public interface Animatable {
public void updateAnimatedState();
}
All objects that want to be notified will implement this interface and can register with the engine
public class Engine {
private List<Animatable> animatables;
private Timer timer;
public Engine() {
animatables = new ArrayList<>(4);
timer = new Timer(10, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (Animatable animatable : animatables) {
animatable.updateAnimatedState();
}
}
});
}
public void add(Animatable animatable) {
animatables.add(animatable);
}
public void start() {
timer.start();
}
public void stop() {
timer.stop();
}
}
Now, all we need to do is update the two components...
public static class ArcsPanel extends JPanel implements Animatable {
//...
#Override
public void updateAnimatedState() {
angle += DELTA;
repaint();
}
}
public class StillClock extends JPanel implements Animatable {
//...
#Override
public void updateAnimatedState() {
setCurrentTime();
repaint();
}
}
You'll note that I've modified your code slightly so that both components now extend from JPanel, extending from JFrame is very limiting and generally discouraged.
Finally, we just need to set it all up...
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();
}
ArcsPanel arcPanel = new ArcsPanel();
StillClock clockPanel = new StillClock();
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(0, 2));
frame.add(arcPanel);
frame.add(clockPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Engine engine = new Engine();
engine.add(arcPanel);
engine.add(clockPanel);
engine.start();
}
});
}
}
Runnable example...
And because I know how confusing a bunch of out-of-context code snippets can be...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
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();
}
ArcsPanel arcPanel = new ArcsPanel();
StillClock clockPanel = new StillClock();
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(0, 2));
frame.add(arcPanel);
frame.add(clockPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Engine engine = new Engine();
engine.add(arcPanel);
engine.add(clockPanel);
engine.start();
}
});
}
public class Engine {
private List<Animatable> animatables;
private Timer timer;
public Engine() {
animatables = new ArrayList<>(4);
timer = new Timer(10, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (Animatable animatable : animatables) {
animatable.updateAnimatedState();
}
}
});
}
public void add(Animatable animatable) {
animatables.add(animatable);
}
public void start() {
timer.start();
}
public void stop() {
timer.stop();
}
}
public interface Animatable {
public void updateAnimatedState();
}
public static class ArcsPanel extends JPanel implements Animatable {
protected static final float DELTA = 1.0f;
private float angle = 0;
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int xCenter = getWidth() / 2;
int yCenter = getHeight() / 2;
int radius = (int) (Math.min(getWidth(), getHeight()) * 0.4);
g2d.setTransform(AffineTransform.getRotateInstance(Math.toRadians(angle), xCenter, yCenter));
int x = xCenter - radius;
int y = yCenter - radius;
g2d.fillArc(x, y, 2 * radius, 2 * radius, 0, 30);
g2d.fillArc(x, y, 2 * radius, 2 * radius, 90, 30);
g2d.fillArc(x, y, 2 * radius, 2 * radius, 180, 30);
g2d.fillArc(x, y, 2 * radius, 2 * radius, 270, 30);
g2d.dispose();
}
#Override
public void updateAnimatedState() {
angle += DELTA;
repaint();
}
}
public class StillClock extends JPanel implements Animatable {
private int hour;
private int minute;
private int second;
public StillClock() {
setCurrentTime();
}
public StillClock(int hour, int minute, int second) {
this.hour = hour;
this.minute = minute;
this.second = second;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// Initialize clock parameters
int clockRadius
= (int) (Math.min(getWidth(), getHeight()) * 0.8 * 0.5);
int xCenter = getWidth() / 2;
int yCenter = getHeight() / 2;
// Draw circle
g.setColor(Color.black);
g.drawOval(xCenter - clockRadius, yCenter - clockRadius,
2 * clockRadius, 2 * clockRadius);
g.drawString("12", xCenter - 5, yCenter - clockRadius + 12);
g.drawString("9", xCenter - clockRadius + 3, yCenter + 5);
g.drawString("3", xCenter + clockRadius - 10, yCenter + 3);
g.drawString("6", xCenter - 3, yCenter + clockRadius - 3);
// Draw second hand
int sLength = (int) (clockRadius * 0.8);
int xSecond = (int) (xCenter + sLength
* Math.sin(second * (2 * Math.PI / 60)));
int ySecond = (int) (yCenter - sLength
* Math.cos(second * (2 * Math.PI / 60)));
g.setColor(Color.red);
g.drawLine(xCenter, yCenter, xSecond, ySecond);
// Draw minute hand
int mLength = (int) (clockRadius * 0.65);
int xMinute = (int) (xCenter + mLength
* Math.sin(minute * (2 * Math.PI / 60)));
int yMinute = (int) (yCenter - mLength
* Math.cos(minute * (2 * Math.PI / 60)));
g.setColor(Color.blue);
g.drawLine(xCenter, yCenter, xMinute, yMinute);
// Draw hour hand
int hLength = (int) (clockRadius * 0.5);
int xHour = (int) (xCenter + hLength
* Math.sin((hour % 12 + minute / 60.0) * (2 * Math.PI / 12)));
int yHour = (int) (yCenter - hLength
* Math.cos((hour % 12 + minute / 60.0) * (2 * Math.PI / 12)));
g.setColor(Color.green);
g.drawLine(xCenter, yCenter, xHour, yHour);
}
public void setCurrentTime() {
// Construct a calendar for the current date and time
Calendar calendar = new GregorianCalendar();
// Set current hour, minute and second
this.hour = calendar.get(Calendar.HOUR_OF_DAY);
this.minute = calendar.get(Calendar.MINUTE);
this.second = calendar.get(Calendar.SECOND);
}
#Override
public void updateAnimatedState() {
setCurrentTime();
repaint();
}
}
}

Zooming effect not shown in the frame

Here is my code below. I am trying to implement zooming by moving the slider.
However, the effect does'nt show. Please help me on this. I am lost. I am new to java and I am using Netbeans for this.
I further need to click on the zoomed image and display the corresponding points in the actual image. How can I make this possible?
public class TrialZoom extends javax.swing.JFrame {
/**
* Creates new form TrialZoom
*/
private float scaleX, scaleY;
Point p = new Point();
Point q = new Point();
Vector<Point> v = new Vector();
Vector<Float> v_scale = new Vector();
public TrialZoom() {
initComponents();
}
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jPanel1 = new javax.swing.JPanel();
jButton1 = new javax.swing.JButton();
jPanel2 = new javax.swing.JPanel();
jPanel3 = new javax.swing.JPanel();
jSlider2 = new javax.swing.JSlider();
jPanel4 = new javax.swing.JPanel();
jLabel1 = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jPanel1.setLayout(new java.awt.GridLayout(1, 0));
jButton1.setText("Done");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
jPanel1.add(jButton1);
getContentPane().add(jPanel1, java.awt.BorderLayout.PAGE_END);
jPanel2.setLayout(new java.awt.BorderLayout());
jPanel3.setLayout(new java.awt.GridLayout(1, 0));
jSlider2.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
jSlider2StateChanged(evt);
}
});
jPanel3.add(jSlider2);
jPanel2.add(jPanel3, java.awt.BorderLayout.PAGE_END);
jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
jLabel1.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
jLabel1MouseClicked(evt);
}
});
javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
jPanel4.setLayout(jPanel4Layout);
jPanel4Layout.setHorizontalGroup(
jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel4Layout.createSequentialGroup()
.addGap(0, 200, Short.MAX_VALUE)
.addComponent(jLabel1)
.addGap(0, 200, Short.MAX_VALUE)))
);
jPanel4Layout.setVerticalGroup(
jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 251, Short.MAX_VALUE)
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel4Layout.createSequentialGroup()
.addGap(0, 125, Short.MAX_VALUE)
.addComponent(jLabel1)
.addGap(0, 126, Short.MAX_VALUE)))
);
jPanel2.add(jPanel4, java.awt.BorderLayout.CENTER);
getContentPane().add(jPanel2, java.awt.BorderLayout.CENTER);
pack();
}// </editor-fold>
private void jSlider2StateChanged(javax.swing.event.ChangeEvent evt) {
// TODO add your handling code here:
int val = ((JSlider) evt.getSource()).getValue();
setScale(val * .01f, val * .01f);
}
private void jLabel1MouseClicked(java.awt.event.MouseEvent evt) {
setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.CROSSHAIR_CURSOR));
p = evt.getPoint();
q = SwingUtilities.convertPoint(evt.getComponent(), p, this);
v.add(p);
v_scale.add(scaleX);
v_scale.add(scaleY);
double c = q.getX();
double d = q.getY();
String x1 = Double.toString(p.getX());
String x2 = Double.toString(p.getY());
Graphics g = this.getGraphics();
paint(g, (int) c, (int) d); // TODO add your handling code here:
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
System.out.println(p.getX() + " " + p.getY() + " " + q.getX() + " " + q.getY());
float sx=v_scale.remove(0);
float sy=v_scale.remove(0);
System.out.println(sx+" "+sy);
dispose();
// TODO add your handling code here:
}
public Vector<Point> first(ImageIcon icon) {
jLabel1.setIcon(icon);
return return_vector();
}
public void paint(Graphics g, int a, int b) {
g.setColor(Color.RED);
g.drawRect(a - 1, b - 1, 3, 3);
g.fillRect(a, b, 2, 2);
}
#Override
public Dimension getPreferredSize() {
int prefWidth;
prefWidth = (int) (jLabel1 == null ? 0 : jPanel4.getWidth() * scaleX);
int prefHeight;
prefHeight = (int) (jLabel1 == null ? 0 : jPanel4.getHeight() * scaleY);
return new Dimension(prefWidth, prefHeight);
}
public void paintComponent(Graphics g) {
if (jLabel1 == null) {
return;
}
int w = (int) (jLabel1.getWidth() * scaleX);
int h = (int) (jLabel1.getHeight() * scaleY);
int x = (getWidth() - w) / 2;
int y = (getHeight() - h) / 2;
ImageIcon img_icon=(ImageIcon) jLabel1.getIcon();
g.drawImage(img_icon.getImage(), x, y, w, h, null);
}
public void setScale(float x, float y) {
this.scaleX = x;
this.scaleY = y;
jLabel1.revalidate();
jLabel1.repaint();
}
public Vector<Point> return_vector() {
return this.v;
}
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(TrialZoom.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(TrialZoom.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(TrialZoom.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(TrialZoom.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new TrialZoom().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JLabel jLabel1;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JPanel jPanel3;
private javax.swing.JPanel jPanel4;
private javax.swing.JSlider jSlider2;
// End of variables declaration
}
First, start with a component that is capable of managing the image and scaling. This should be as self contained as you can make it. This allows you to decouple your program and focus on individual responsibilities of the application.
Next, you need to maintain a list of normalised points. The reason for normalising them is to ensure that the points will continue to be rendered at the right locations when the image scaled...
Take a look at Performing Custom Painting for more details
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.Image;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class ZoomExample {
public static void main(String[] args) {
new ZoomExample();
}
public ZoomExample() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new ZoomPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ZoomPane extends JPanel {
private JSlider slider;
private ZoomImagePane zoomImagePane;
public ZoomPane() {
zoomImagePane = new ZoomImagePane();
slider = new JSlider(1, 200);
slider.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
zoomImagePane.setScale((float) slider.getValue() / 100f);
}
});
setLayout(new BorderLayout());
add(slider, BorderLayout.SOUTH);
add(zoomImagePane);
slider.setValue(100);
}
}
public class ZoomImagePane extends JPanel {
private float scale = 0f;
private BufferedImage master;
private Image scaled;
private List<Point2D> clickPoints;
public ZoomImagePane() {
clickPoints = new ArrayList<>(25);
try {
master = ImageIO.read(new File("/path/to/image"));
setScale(1f);
} catch (IOException ex) {
ex.printStackTrace();
}
addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
Point p = e.getPoint();
Point2D scaledPoint = new Point2D.Float();
int xOffset = (getWidth() - scaled.getWidth(null)) / 2;
int yOffset = (getHeight() - scaled.getHeight(null)) / 2;
float x = (float)(p.x - xOffset) / (float)scaled.getWidth(null);
float y = (float)(p.y - yOffset) / (float)scaled.getHeight(null);
scaledPoint.setLocation(x, y);
clickPoints.add(scaledPoint);
repaint();
}
});
}
protected void setScale(float value) {
if (scale != value) {
scale = value;
scaled = master.getScaledInstance((int) ((float) master.getWidth() * scale), -1, Image.SCALE_SMOOTH);
revalidate();
repaint();
}
}
#Override
public Dimension getPreferredSize() {
Dimension size = new Dimension(200, 200);
if (scaled != null) {
size = new Dimension(scaled.getWidth(this), scaled.getHeight(this));
}
return size;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (scaled != null) {
int x = (getWidth() - scaled.getWidth(this)) / 2;
int y = (getHeight() - scaled.getHeight(this)) / 2;
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(scaled, x, y, this);
g2d.setColor(Color.RED);
for (Point2D p : clickPoints) {
int xPos = x + ((int)(p.getX() * scaled.getWidth(this)) - 5);
int yPos = y + ((int)(p.getY() * scaled.getHeight(this)) - 5);
g2d.fillOval(xPos, yPos, 10, 10);
}
g2d.dispose();
}
}
}
}

Categories