Translate, Scale, Rotate and Reflex Rectangle with java graphics 2d - java

I got a problem, what I want to do is basically create a panel where I can Translate, Scale, Rotate and Reflex a Rectangle by giving some info on textbox and click a button, I already drawn a rectangle and I can move it before drawing it, but I need to transform it after drawn and what I want is to only transform the rectangle and not the guide lines, how can I do this? this is my code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Ventana extends JFrame implements ActionListener {
MiPanel panelFigura = new MiPanel();
JPanel panelBotones = new JPanel();
JButton btnTransladar = new JButton("Translador"); // Means translate
JButton btnEscala = new JButton("Escala"); // Means Scale
JButton btnRotar = new JButton("Rotar"); // Means Rotate
JTextField txT = new JTextField(4);
JTextField tyT = new JTextField(4);
JTextField exT = new JTextField(4);
JTextField eyT = new JTextField(4);
JTextField gradoT = new JTextField(3);
public Ventana() {
setSize(800, 600);
setVisible(true);
setTitle("Unidad 2");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
add(panelFigura);
panelBotones.add(new JLabel("x: "));
panelBotones.add(txT);
panelBotones.add(new JLabel("y: "));
panelBotones.add(tyT);
btnTransladar.addActionListener(this);
panelBotones.add(btnTransladar);
panelBotones.add(new JLabel("x: "));
panelBotones.add(exT);
panelBotones.add(new JLabel("y: "));
panelBotones.add(eyT);
panelBotones.add(btnEscala);
panelBotones.add(new JLabel("ยบ: "));
panelBotones.add(gradoT);
panelBotones.add(btnRotar);
panelBotones.setBackground(Color.LIGHT_GRAY);
btnRotar.addActionListener(this);
btnTransladar.addActionListener(this);
btnEscala.addActionListener(this);
add(panelBotones, BorderLayout.SOUTH);
}
public class MiPanel extends JPanel {
public int tx = 0, ty = 0, ex = 0, ey = 0, grado = 0; // tx and ty are
// how many
// pixel is the
// rectangle
// moving, ex
// and ex is how
// much is
// scaling and
// grado is the
// angle of the
// rotation
Rectangle2D.Double rectangulo = new Rectangle2D.Double(tx, ty, 60, 60);
public MiPanel() {
this.setSize(800, 400);
this.setBackground(Color.WHITE);
}
public void paintComponent(Graphics g) {
// super.paintComponent( g );
Graphics2D g2D = (Graphics2D) g;
g2D.translate((this.getWidth() / 2), (this.getHeight() / 2));
g2D.drawLine((0 - (this.getWidth() / 2)), 0, (this.getWidth() / 2),
0);
g2D.drawLine(0, this.getHeight(), 0, (0 - this.getHeight() / 2));
g2D.draw(rectangulo);
}
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btnTransladar) {
panelFigura.tx = Integer.getInteger(txT.getText());
panelFigura.ty = Integer.getInteger(tyT.getText());
}
if (e.getSource() == btnEscala) {
panelFigura.ex = Integer.getInteger(exT.getText());
panelFigura.ey = Integer.getInteger(eyT.getText());
}
if (e.getSource() == btnRotar) {
panelFigura.grado = Integer.getInteger(gradoT.getText());
}
}
}
Thanks for helping me out!

Related

Swing Java Rotate JLabel but text be erased

I'm using swing Java to try to do something with java. Now I want to rotate JLabel and I did that. But unfortunelately, a part of my text in JLabel is erased (as in the image below). I have tried search but seem no one has problems as same as mine. I guess it's occured caused JLabels they overlaped.
and this is my code
serviceName[j] = new JLabel(name){
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
AffineTransform aT = g2.getTransform();
Shape oldshape = g2.getClip();
aT.rotate(Math.toRadians(300));
g2.setTransform(aT);
g2.setClip(oldshape);
super.paintComponent(g);
}
};
Can you give me the way to solved it
You should restore original transform and clip after your painting. Like this
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
AffineTransform aT = g2.getTransform();
Shape oldshape = g2.getClip();
g2.rotate(Math.toRadians(300));
super.paintComponent(g);
g2.setTransform(aT);
g2.setClip(oldshape);
}
Your JLabel subclass should also override getPreferredSize() to report the size it will be when it is rotated; otherwise the any layout manager that uses asks your component for its preferred size will use JLabel's version, which assumes the text is drawn horizontally.
Instead of attempting to rotate the component, another approach would be to create a Text Icon and add the Icon to a JLabel.
Once you have created the TextIcon you can then create a Rotated Icon to add to the label. The RotatedIcon will calculate the proper size of the Icon so therefore the size of the label will also be correct and no custom painting is required.
So the basic code would be something like:
JLabel label = new JLabel();
TextIcon textlIcon = new TextIcon(label, "Rotated Text");
label.setIcon( new RotatedIcon(textIcon, 300) );
Edit:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.border.*;
import javax.swing.table.*;
import java.io.*;
public class SSCCE extends JPanel
{
public SSCCE()
{
OverlapLayout layout = new OverlapLayout(new Point(20, 0));
setLayout( layout );
addLabel("one");
addLabel("two");
addLabel("three or more");
addLabel("four");
}
private void addLabel(String text)
{
JLabel label = new JLabel();
TextIcon textIcon = new TextIcon(label, text);
label.setIcon( new RotatedIcon(textIcon, 300) );
label.setVerticalAlignment(JLabel.BOTTOM);
add(label);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE());
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
This example also uses the Overlap Layout so the labels can be painted over top of one another.
You may find some hints from this small program. Experiment on the values of setPrefferedSize to have more ideas. If you still can't solve the problem, please edit and add more codes in your question above.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import javax.swing.*;
public class InclinedLabels extends JFrame{
/** Creates a new instance of InclinedLabels */
public InclinedLabels() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JPanel jPanel1 = new JPanel();
jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
add(jPanel1);
JPanel jPanel2 = new JPanel();
jPanel2.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
jPanel2.setPreferredSize(new Dimension(10, 100));
add(jPanel2, BorderLayout.NORTH);
jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
jPanel1.setPreferredSize(new java.awt.Dimension(200, 200));
java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
setBounds((screenSize.width-400)/2, (screenSize.height-352)/2, 300, 352);
String str = "The quick brown fox jumps over the lazy dog";
String[] word = str.split(" ");
JLabel[] serviceName = new JLabel[str.length()];
String name;
for (int j=0; j<word.length; j++) {
name = word[j];
serviceName[j] = new JLabel(name){
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
AffineTransform aT = g2.getTransform();
Shape oldshape = g2.getClip();
aT.rotate(Math.toRadians(300));
g2.setTransform(aT);
g2.setClip(oldshape);
super.paintComponent(g);
}
};
serviceName[j].setPreferredSize(new Dimension(50,20));
serviceName[j].setBorder(BorderFactory.createLineBorder(Color.RED));
jPanel1.add(serviceName[j]);
}
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new InclinedLabels().setVisible(true);
}
});
}
}
Update:
I found a much closer hint that may solve this problem. The big factor here is the component layout. The null layout allows overlapping of JLabel components so it is the most appropriate layout to be used here. Then you have to customize the location and size of the labels through the setBounds method. In the code below there is serviceName[j].setBounds(xOffset + j*20,180, 170, 15); So in every loop iteration, the x location of the label is increased by 20. The size of all labels is 170 by 15. I also placed temporary borders to the components to help in understanding the output.
import java.awt.*;
import java.awt.geom.AffineTransform;
import javax.swing.*;
public class InclinedLabels extends JFrame{
/** Creates a new instance of InclinedLabels */
public InclinedLabels() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
setBounds((screenSize.width-360)/2, (screenSize.height-352)/2, 360, 352);
JPanel jPanel1 = new JPanel();
jPanel1.setBorder(BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
jPanel1.setLayout(null); // null layout allows overlapping of components
add(jPanel1);
JPanel jPanel2 = new JPanel();
jPanel2.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
jPanel2.setPreferredSize(new Dimension(10, 100));
add(jPanel2, BorderLayout.NORTH);
String str = "The quick brown fox jumpsssssssssssss123456 over the lazy dogssssssssssssss123456";
String[] word = str.split(" ");
JLabel[] serviceName = new JLabel[str.length()];
String name;
int xOffset = 30;
for (int j=0; j<word.length; j++) {
name = word[j];
serviceName[j] = new JLabel(name){
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
AffineTransform aT = g2.getTransform();
Shape oldshape = g2.getClip();
aT.rotate(Math.toRadians(300));
g2.setTransform(aT);
g2.setClip(oldshape);
super.paintComponent(g2);
}
};
serviceName[j].setBounds(xOffset + j*20,180, 170, 15); // experiment here
serviceName[j].setBorder(BorderFactory.createLineBorder(Color.RED));
jPanel1.add(serviceName[j]);
}
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new InclinedLabels().setVisible(true);
}
});
}
}
The limitation that I found in the code above is the width of the parent panel. In the example, the label having the text dogssssssssssssss123456 was not printed in whole. This can be overcome by increasing the width of the frame which in turn increases the width of jPanel1.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
public class Test {
public static void main(String[] args) {
// Create the first label, which will be rotated later.
Test.RotateLabel one = new Test.RotateLabel( "Rotated", 100, 100 );
one.setRotation( 270 );
JLayeredPane pane = new JLayeredPane();
pane.setLayer( one, JLayeredPane.DEFAULT_LAYER );
pane.add( one );
pane.setBorder(new javax.swing.border.LineBorder(Color.BLACK,1));
// Put the container pane in a frame and show the frame.
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( pane );
frame.setSize( 500, 500 );
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
static class RotateLabel extends JLabel {
private static final long serialVersionUID = 1L;
private int angle = 0;
public RotateLabel( String text, int x, int y ) {
super( text );
setBorder( new javax.swing.border.CompoundBorder(
new javax.swing.border.LineBorder( Color.red, 1), getBorder() ) );
int width = getPreferredSize().width;
int height = getPreferredSize().height;
setBounds(x, y, width, height);
}
#Override
public void paintComponent( Graphics g ) {
Graphics2D gx = (Graphics2D) g;
Shape old = gx.getClip();
gx.rotate(-Math.toRadians(45), getWidth() / 2, getHeight() / 2);
gx.setClip(old);
super.paintComponent(gx);
}
public void setRotation( int angle ) { this.angle = angle; }
}

Backup for image that is drawn on in Java

In my application, there are things marked on an image by clicking on the image. That is done by setting the image as an Icon to a JLabel and adding a MousePressed method
I want to add a feature for the users to redo the last step now and need a backupimage for that.
The following is a code example:
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.Color;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class BuffImgTest {
private BufferedImage buffimg, scaledimg, backupscaledimg;
private Image img;
private JFrame frame;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
BuffImgTest window = new BuffImgTest();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public BuffImgTest() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
final JLabel label = new JLabel("");
label.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent arg0) {
Graphics graphics = scaledimg.getGraphics();
graphics.setColor(Color.RED);
graphics.drawString("Test", arg0.getX(), arg0.getY());
Image img = Toolkit.getDefaultToolkit().createImage(
scaledimg.getSource());
label.setIcon(new ImageIcon(img));
}
});
label.setBounds(10, 34, 414, 201);
try {
buffimg = ImageIO.read(new File("test.jpg"));
scaledimg = getScaledImage(buffimg, label.getWidth(),
label.getHeight());
backupscaledimg = scaledimg;
// backupscaledimg=getScaledImage(buffimg,label.getWidth(),label.getHeight());
Image img = Toolkit.getDefaultToolkit().createImage(
scaledimg.getSource());
label.setIcon(new ImageIcon(img));
} catch (Exception e) {
System.out.println(e);
}
frame.getContentPane().add(label);
JButton btnNewButton = new JButton("Restart Step");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
scaledimg = backupscaledimg;
Image img = Toolkit.getDefaultToolkit().createImage(
scaledimg.getSource());
label.setIcon(new ImageIcon(img));
}
});
btnNewButton.setBounds(111, 238, 89, 23);
frame.getContentPane().add(btnNewButton);
}
public static BufferedImage getScaledImage(BufferedImage image, int width,
int height) throws IOException {
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
double scaleX = (double) width / imageWidth;
double scaleY = (double) height / imageHeight;
AffineTransform scaleTransform = AffineTransform.getScaleInstance(
scaleX, scaleY);
AffineTransformOp bilinearScaleOp = new AffineTransformOp(
scaleTransform, AffineTransformOp.TYPE_BILINEAR);
return bilinearScaleOp.filter(image, new BufferedImage(width, height,
image.getType()));
}
}
It is not working as intended.
If I use the commented line backupscaledimg = getScaledImage(buffimg,label.getWidth(),label.getHeight()); instead of backupscaledimg = scaledimg;, it is working as expected.
The problem is that I want to do several steps of drawing things on the image, and it can only be redone the first time like that. From what I know the problem might be, that the command backupscaledimg = scaledimg is only creating a pointer for backupscaledimg pointing to scaledimg which results in both of them altering.
I don't want to save a new imagefile on each step though.
Is there any way around this? (found the scaling function on here by the way thanks for that anonymous)
Made some changes
Using GridBagLayout
Able to reset back to original image by pressing "Restart Step"
Able to undo last action with the use of an image stack (i.e. a Stack of BufferedImage)
Example code:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Stack;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import java.awt.Color;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class BuffImgTest {
private BufferedImage scaledImg, originalScaledImg;
private JFrame frame;
private Stack<BufferedImage> imageStack = new Stack<>();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
BuffImgTest window = new BuffImgTest();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public BuffImgTest() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout());
JPanel panel = new JPanel(new GridBagLayout());
final JLabel imgLabel = new JLabel("");
imgLabel.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent arg0) {
// Add current image to the image stack
imageStack.add(copyImage(scaledImg));
// Change the image
Graphics graphics = scaledImg.getGraphics();
graphics.setColor(Color.BLACK);
graphics.setFont(new Font("Arial", Font.BOLD, 32));
graphics.drawString("TEST", arg0.getX(), arg0.getY());
// Update label
Image img = Toolkit.getDefaultToolkit().createImage(
scaledImg.getSource());
imgLabel.setIcon(new ImageIcon(img));
}
});
imgLabel.setSize(500, 500);
imgLabel.setPreferredSize(new Dimension(500, 500));
try {
BufferedImage buffImg = ImageIO.read(new File("test.jpg"));
scaledImg = getScaledImage(buffImg, imgLabel.getWidth(),
imgLabel.getHeight());
// Clone it first
originalScaledImg = copyImage(scaledImg);
Image img = Toolkit.getDefaultToolkit().createImage(
scaledImg.getSource());
imgLabel.setIcon(new ImageIcon(img));
} catch (Exception e) {
System.out.println(e);
}
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.insets = new Insets(20, 10, 10, 10);
panel.add(imgLabel, c);
JButton restartBtn = new JButton("Restart Step");
restartBtn.setFont(new Font("Arial", Font.ITALIC, 20));
restartBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
// Clear the image stack
imageStack.clear();
// Reset the image
scaledImg = copyImage(originalScaledImg);
Image img = Toolkit.getDefaultToolkit().createImage(
scaledImg.getSource());
imgLabel.setIcon(new ImageIcon(img));
}
});
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 1;
c.anchor = GridBagConstraints.CENTER;
c.insets = new Insets(10, 10, 5, 10);
panel.add(restartBtn, c);
JButton undoBtn = new JButton("Undo Last");
undoBtn.setFont(new Font("Arial", Font.ITALIC, 20));
undoBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if(imageStack.isEmpty()) {
JOptionPane.showMessageDialog(frame, "Cannot undo anymore!");
return;
}
// Get the previous image
scaledImg = copyImage(imageStack.pop());
Image img = Toolkit.getDefaultToolkit().createImage(
scaledImg.getSource());
imgLabel.setIcon(new ImageIcon(img));
}
});
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 2;
c.anchor = GridBagConstraints.CENTER;
c.insets = new Insets(5, 10, 20, 10);
panel.add(undoBtn, c);
frame.getContentPane().add(panel, BorderLayout.CENTER);
frame.setSize(800, 800);
}
/** For copying image */
public static BufferedImage copyImage(BufferedImage source){
BufferedImage b = new BufferedImage(
source.getWidth(), source.getHeight(), source.getType());
Graphics g = b.getGraphics();
g.drawImage(source, 0, 0, null);
g.dispose();
return b;
}
public static BufferedImage getScaledImage(BufferedImage image, int width,
int height) throws IOException {
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
double scaleX = (double) width / imageWidth;
double scaleY = (double) height / imageHeight;
AffineTransform scaleTransform = AffineTransform.getScaleInstance(
scaleX, scaleY);
AffineTransformOp bilinearScaleOp = new AffineTransformOp(
scaleTransform, AffineTransformOp.TYPE_BILINEAR);
return bilinearScaleOp.filter(image, new BufferedImage(width, height,
image.getType()));
}
}
Edited Image:
Image after pressing "Restart step":
Pressing "Undo Last" when image stack is empty:
Note:
Code for copying image is from this answer by APerson

Java form elements not showing up fully until activated i.e. clicked on

I've been trying to add Java form elements such as a textField and a passwordField to a fullscreen exclusive mode frame. The issue i've been having is that when I run the code, my form elements don't show up fully or not at all until I actually click on them.
Here's my code:
Master.java
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class Master extends JFrame {
private static final long serialVersionUID = -4927941474660261348L;
static GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
static GraphicsDevice gd = ge.getDefaultScreenDevice();
static int WIDTH = gd.getDisplayMode().getWidth();
static int HEIGHT = gd.getDisplayMode().getHeight();
static Toolkit toolkit = Toolkit.getDefaultToolkit();
static Graphics2D g2d = null;
static FontMetrics metrics = null;
static URL vignetteURL = null;
static Image vignette = null;
static Rectangle red = new Rectangle(WIDTH - 35, 0, 35, 35);
public Master() {
super("Project Zenith");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
getContentPane().setLayout(null);
setUndecorated(true);
setResizable(false);
gd.setFullScreenWindow(this);
repaint();
setIconImage(new ImageIcon(getClass().getResource("images/hex.png")).getImage());
vignetteURL = getClass().getResource("images/vignette2.png");
addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
if(e.getX() >= red.getX() && e.getY() <= red.getHeight()) {
closeClicked();
}
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent arg0) {
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
});
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
g2d = (Graphics2D) g;
vignette = toolkit.getImage(vignetteURL);
g2d.clearRect(0, 0, getWidth(), getHeight());
g2d.setFont(new Font("Bebas Neue", Font.PLAIN, 25));
metrics = g2d.getFontMetrics();
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setColor(new Color(168, 168, 168, 200));
g2d.drawString("Project Zenith", 10, HEIGHT - 10);
g2d.setColor(new Color(0xFFA6A6));
g2d.fill(red);
g2d.drawImage(vignette, 0, 0, WIDTH, HEIGHT, this);
}
public void closeClicked() {
System.exit(0);
}
}
Login.java
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.RoundRectangle2D;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
public class Login extends Master {
private static final long serialVersionUID = 1L;
static Master l;
static JTextField username;
static JTextField password;
static Graphics2D g2d = null;
static FontMetrics metrics = null;
static RoundRectangle2D loginRect = new RoundRectangle2D.Float((WIDTH / 2) - ((WIDTH / 4) / 2), (HEIGHT / 2) - ((HEIGHT / 4) / 2), (WIDTH / 4), (HEIGHT / 4), 20, 20);
Login() {
l = this;
Font inputFont = new Font("Calibri", Font.PLAIN, 15);
username = new JTextField();
username.setBounds((WIDTH / 2) - (((int) loginRect.getY() - 10) / 2), (int) loginRect.getY() + 60, (int) loginRect.getY() - 10, 18);
username.setFont(inputFont);
username.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
username.setEditable(true);
username.setBackground(new Color(0xE6E6E6));
//username.setVisible(true);
getContentPane().add(username);
password = new JPasswordField();
password.setBounds((WIDTH / 2) - (((int) loginRect.getY() - 10) / 2), (int) loginRect.getY() + 110, (int) loginRect.getY() - 10, 18);
password.setFont(inputFont);
password.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
password.setEditable(true);
password.setBackground(new Color(0xE6E6E6));
//password.setVisible(true);
getContentPane().add(password);
JButton loginButton = new JButton("Login");
loginButton.setBounds((WIDTH / 2) - 40, (int) loginRect.getY() + 155, 80, 20);
loginButton.setFont(inputFont);
loginButton.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
loginButton.setBackground(new Color(0xE6E6E6));
//loginButton.setVisible(true);
loginButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println(username.getText());
}
});
getContentPane().add(loginButton);
repaint();
setVisible(true);
}
public void paint(Graphics g) {
super.paint(g);
g2d = (Graphics2D) g;
metrics = g2d.getFontMetrics();
g2d.setColor(Color.WHITE);
g2d.fill(loginRect);
g2d.setColor(new Color(0xA8A8A8));
g2d.drawString("Access Terminal", (Master.WIDTH / 2) - (metrics.stringWidth("Access Terminal") / 2), (int) loginRect.getY() + metrics.getHeight() + 2);
}
public static void main(String [] args) {
new Login();
}
}
Start by taking a look at Painting in AWT and Swing and Performing Custom Painting for an explanation of how painting works in Swing.
The basic problem is:
You're breaking the painting chain
You're painting over child components
This is one (of many reasons) why you shouldn't override paint of top level containers. Instead, start by using a JPanel and overriding it's paintComponent (calling super.paintComponent before you perform any custom painting)
You should also make use of appropriate layout manager to better handle the differences in resolutions and font rendering requirements.
Have a look at Laying Out Components Within a Container for more details
With a little clever planning, you can do some pretty advance things
Now, obviously this isn't in full screen, but that's kind of the point, you can now uncomment the line gd.setFullScreenWindow(frame); and it will auto-magically realign itself, through the power of layout managers.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.RoundRectangle2D;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
Login login = new Login();
JFrame frame = new JFrame("Project Zenith");
frame.setUndecorated(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(login);
frame.pack();
frame.setLocationRelativeTo(null);
// gd.setFullScreenWindow(frame);
frame.setVisible(true);
}
});
}
public static class Master extends JPanel {
private static final long serialVersionUID = -4927941474660261348L;
private Rectangle closeRect;
public Master() {
addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
if (e.getX() >= closeRect.getX() && e.getY() <= closeRect.getHeight()) {
closeClicked();
}
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent arg0) {
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
});
}
#Override
public void invalidate() {
super.invalidate();
closeRect = new Rectangle(getWidth() - 35, 0, 35, 35);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setFont(new Font("Bebas Neue", Font.PLAIN, 25));
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setColor(new Color(168, 168, 168, 200));
FontMetrics fm = g2d.getFontMetrics();
int y = (getHeight() - fm.getHeight()) + fm.getAscent();
g2d.drawString("Project Zenith", 10, y);
g2d.setColor(new Color(0xFFA6A6));
g2d.fill(closeRect);
}
public void closeClicked() {
System.exit(0);
}
}
public static class Login extends Master {
private static final long serialVersionUID = 1L;
private JTextField username;
private JTextField password;
Login() {
Font inputFont = new Font("Calibri", Font.PLAIN, 15);
setLayout(new GridBagLayout());
JPanel content = new JPanel(new GridBagLayout()) {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
RoundRectangle2D loginRect = new RoundRectangle2D.Float(0, 0, getWidth() - 1, getHeight() - 1, 20, 20);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.WHITE);
g2d.fill(loginRect);
g2d.setColor(new Color(0xA8A8A8));
g2d.draw(loginRect);
}
};
content.setBorder(new EmptyBorder(20, 20, 20, 20));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.insets = new Insets(0, 0, 25, 0);
gbc.gridx = 0;
gbc.gridy = 0;
JLabel label = new JLabel("Access Terminal");
label.setFont(new Font("Bebas Neue", Font.PLAIN, 25));
label.setForeground(new Color(0xA8A8A8));
content.add(label, gbc);
gbc.gridy++;
username = new JTextField(25);
username.setFont(inputFont);
username.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
username.setEditable(true);
username.setBackground(new Color(0xE6E6E6));
//username.setVisible(true);
content.add(username, gbc);
gbc.gridy++;
password = new JPasswordField(25);
password.setFont(inputFont);
password.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
password.setEditable(true);
password.setBackground(new Color(0xE6E6E6));
//password.setVisible(true);
content.add(password, gbc);
gbc.gridy++;
JButton loginButton = new JButton("Login");
loginButton.setFont(inputFont);
loginButton.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
loginButton.setBackground(new Color(0xE6E6E6));
loginButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println(username.getText());
}
});
content.add(loginButton, gbc);
add(content);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
}
Basically, in your Login view, I've used compounding components to generate the "rounded border" effect, creating a JPanel and overriding it's paintComponent method to paint the effect. This provides me with layout information from the child components in order to make determinations about how big the effect should be. This is then added into a Login panel itself and through the use of layout managers, it all gets centered

why can't I draw any stuffs on Frame in java?

Coding is here.
I can't create any rectangle or circle inside frame.
the object of this project is to create converting celcius 2 Farenheit & Farenheit 2 Celcius.
so what I want is, please teach me to how to draw rectangle or oval in side the frame.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class C2F extends JComponent{
private double input1, output1;
private double input2, output2;
JPanel center = new JPanel();
JPanel top = new JPanel();
JPanel east = new JPanel();
JPanel south = new JPanel();
//for giving input & output
C2F(){
JFrame frame = new JFrame();
frame.setTitle("C2F");
frame.setSize(700,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.getContentPane().add(top,BorderLayout.NORTH);
frame.getContentPane().add(center,BorderLayout.CENTER);
frame.getContentPane().add(south,BorderLayout.SOUTH);
frame.getContentPane().add(east,BorderLayout.EAST);
frame.setVisible(true);
CC2F();
}
public void CC2F(){
//making frame
//give specific location
JLabel L1 = new JLabel("Please input Celcius or Fahrenheit to Convert");
top.add(L1);
JLabel l1 = new JLabel("Cel -> Fah");
south.add(l1);
JTextField T1 = new JTextField(12);
south.add(T1);
JButton B1 = new JButton("Convert");
south.add(B1);
JLabel l2 = new JLabel("Fah -> Cel");
south.add(l2);
JTextField T2 = new JTextField(12);
south.add(T2);
JButton B2 = new JButton("Convert");
south.add(B2);
//to create buttons and labels to give an answer
B1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
input1 = Double.parseDouble(T1.getText());
output1 = input1 *(9/5) + 32;
T2.setText(""+output1);
repaint();
}
});
B2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
input2 = Double.parseDouble(T2.getText());
output2 = (input2 - 32)/9*5;
T1.setText(""+output2);
}
});
//making events
//placing the buttons and labels
output1 = 0;
output2 = 0;
//initialize the value
}
public void paintComponent(Graphics g) {
//error spots. it compiles well. But this is not what I want.
super.paintComponent(g);
Graphics2D gg = (Graphics2D) g;
gg.setColor(Color.BLACK);
gg.drawOval(350, 500,12,12);
gg.setColor(Color.RED);
gg.fillRect(350, 500, 10,(int) output1);
gg.fillOval(350, 500, 10, 10);
gg.setColor(Color.RED);
gg.fillRect(350, 500, 10,(int) output2);
gg.fillOval(350, 500, 10, 10);
//to draw stuffs
}
public static void main(String[] args)
{//to run the program
new C2F();
}
}
You never actually add C2F to anything that would be able to paint it, therefore your paint method will never be called.
You should override paintComponent instead of paint, as you've broken the paint chain for the component which could cause no end of issues with wonderful and interesting paint glitches. Convention would also suggest that you should call super.paintComponent (when overriding paintComponent) as well before you perform any custom painting
See Painting in AWT and Swing and Performing Custom Painting for more details
As a general piece of advice, I'd discourage you from creating a frame within the constructor of another component, this will make the component pretty much unusable again (if you wanted to re-use it on another container for example)
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.event.ActionEvent;
import java.awt.event.ActionListener;
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.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class C2F extends JComponent {
public C2F() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
TestPane center = new TestPane();
JPanel top = new JPanel();
JPanel east = new JPanel();
JPanel south = new JPanel();
//give specific location
JLabel L1 = new JLabel("Please input Celcius or Fahrenheit to Convert");
top.add(L1);
JLabel l1 = new JLabel("Cel -> Fah");
south.add(l1);
JTextField T1 = new JTextField(12);
south.add(T1);
JButton B1 = new JButton("Convert");
south.add(B1);
JLabel l2 = new JLabel("Fah -> Cel");
south.add(l2);
JTextField T2 = new JTextField(12);
south.add(T2);
JButton B2 = new JButton("Convert");
south.add(B2);
//to create buttons and labels to give an answer
B1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
double input1 = Double.parseDouble(T1.getText());
double output1 = input1 * (9 / 5) + 32;
T2.setText("" + output1);
center.setOutput1(output1);
}
});
B2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
double input2 = Double.parseDouble(T2.getText());
double output2 = (input2 - 32) / 9 * 5;
T1.setText("" + output2);
center.setOutput2(output2);
}
});
//making events
frame.getContentPane().add(top, BorderLayout.NORTH);
frame.getContentPane().add(center, BorderLayout.CENTER);
frame.getContentPane().add(south, BorderLayout.SOUTH);
frame.getContentPane().add(east, BorderLayout.EAST);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private double output1, output2;
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 600);
}
public void setOutput1(double output1) {
this.output1 = output1;
repaint();
}
public void setOutput2(double output2) {
this.output2 = output2;
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLACK);
g2d.drawOval(350, 500, 12, 12);
g2d.setColor(Color.RED);
g2d.fillRect(350, 0, 10, (int) output1);
g2d.fillOval(350, 0, 10, 10);
g2d.setColor(Color.BLUE);
g2d.fillRect(350, 0, 10, (int) output2);
g2d.fillOval(350, 0, 10, 10);
g2d.dispose();
}
}
public static void main(String[] args) {//to run the program
new C2F();
}
}

Displaying size in JTextbox based on size of dynamic circle

I'm trying to create a Java program that draws a circle, sliders can resize the circle, 3 other sliders control RGB settings. The problem is that i cannot get the stats (diameter, area and circumference) to display in the JTextBox. Please help its driving me mad!!!
Thanks!
CircleModifier.java
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
#SuppressWarnings("serial")
public class CircleModifier extends JFrame implements ChangeListener {
public DrawingPanel drawingPanel;
public InfoPanel infoPanel;
public JPanel sizePanel;
private JPanel sliderPanel;
private JSlider sizeSlider, redColorSlider, greenColorSlider,
blueColorSlider;
private JLabel sizeLabel, redLabel, greenLabel, blueLabel;
public CircleModifier() {
super("Circle Modifier Application");
setLayout(new BorderLayout());
drawingPanel = new DrawingPanel();
add(drawingPanel, BorderLayout.CENTER);
sliderPanel = new JPanel();
add(sliderPanel, BorderLayout.EAST);
sliderPanel.setBackground(Color.WHITE);
infoPanel = new InfoPanel();
add(infoPanel, BorderLayout.SOUTH);
sliderPanel.setLayout(new GridLayout(2, 4, 0, 1));
sizeLabel = new JLabel("-Size-");
sizeLabel.setForeground(Color.BLACK);
setSizeSlider(new JSlider(JSlider.VERTICAL, 0, 350, 10));
getSizeSlider().setMajorTickSpacing(50);
getSizeSlider().setMinorTickSpacing(25);
getSizeSlider().setPaintTicks(true);
getSizeSlider().setPaintLabels(true);
getSizeSlider().setBackground(Color.WHITE);
getSizeSlider().addChangeListener(this);
redColorSlider = new JSlider(JSlider.VERTICAL, 0, 255, 0);
redColorSlider.setMajorTickSpacing(20);
redColorSlider.setMinorTickSpacing(5);
redColorSlider.setPaintTicks(true);
redColorSlider.setPaintLabels(true);
redColorSlider.setBackground(Color.WHITE);
redColorSlider.addChangeListener(this);
redLabel = new JLabel("-Red-");
redLabel.setForeground(Color.RED);
greenColorSlider = new JSlider(JSlider.VERTICAL, 0, 255, 0);
greenColorSlider.setMajorTickSpacing(20);
greenColorSlider.setMinorTickSpacing(5);
greenColorSlider.setPaintTicks(true);
greenColorSlider.setPaintLabels(true);
greenColorSlider.setBackground(Color.WHITE);
greenColorSlider.addChangeListener(this);
greenLabel = new JLabel("-Green-");
greenLabel.setForeground(Color.GREEN);
blueColorSlider = new JSlider(JSlider.VERTICAL, 0, 255, 0);
blueColorSlider.setMajorTickSpacing(20);
blueColorSlider.setMinorTickSpacing(5);
blueColorSlider.setPaintTicks(true);
blueColorSlider.setPaintLabels(true);
blueColorSlider.setBackground(Color.WHITE);
blueColorSlider.addChangeListener(this);
blueLabel = new JLabel("-Blue-");
blueLabel.setForeground(Color.BLUE);
sliderPanel.add(sizeLabel);
sliderPanel.add(redLabel);
sliderPanel.add(greenLabel);
sliderPanel.add(blueLabel);
sliderPanel.add(getSizeSlider());
sliderPanel.add(redColorSlider);
sliderPanel.add(greenColorSlider);
sliderPanel.add(blueColorSlider);
setSize(800, 500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public void stateChanged(ChangeEvent e) {
int size = getSizeSlider().getValue();
drawingPanel.setDiameter(size);
sizeLabel.setText("-Size-");
int red = redColorSlider.getValue();
int green = greenColorSlider.getValue();
int blue = blueColorSlider.getValue();
drawingPanel.setNewCircleColor(red, green, blue);
redLabel.setText("-Red-");
greenLabel.setText("-Green-");
blueLabel.setText("-Blue-");
}
public static void main(String[] args) {
new CircleModifier();
}
public JSlider getSizeSlider() {
return sizeSlider;
}
public void setSizeSlider(JSlider sizeSlider) {
this.sizeSlider = sizeSlider;
}
}
InfoPane.java
import javax.swing.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import java.awt.*;
import java.awt.event.*;
import java.awt.*;
#SuppressWarnings("serial")
public class InfoPanel extends JPanel {
JTextArea textarea;
JLabel label;
private JTextArea display;
public InfoPanel() {
setLayout(new FlowLayout());
label = new JLabel("Information");
add(label);
display = new JTextArea(5, 30);
display.setText("The Radius is: " + "\nThe Diameter is: "
+ "Dynamic diameter to display here!" + "\nThe Area is: "
+ "\nThe Circumference is: ");
add(display);
}
}
DrawingPanel.java
import javax.swing.*;
import java.awt.*;
#SuppressWarnings("serial")
public class DrawingPanel extends JPanel {
public static String size;
int diameter = 1;
int red = 255, green = 255, blue = 255;
Color newCircleColor = new Color(red, green, blue);
public void paintComponent(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(newCircleColor);
g.fillOval(10, 10, diameter, diameter);
}
public void setDiameter(int newSize) {
diameter = newSize;
repaint();
}
public void setNewCircleColor(int red, int green, int blue) {
newCircleColor = new Color(red, green, blue);
repaint();
}
}
Give InfoPanel a public method,
public void textareaSetText(String text) {
textarea.setText(text);
}
And inside of this, set the text of the JTextArea variable.
Then call this method from within CircleModifier's stateChanged(...) method. If you want to append text, you could also give InfoPanel a similar textareaAppendText(String text) method.

Categories