Run a WindowBuilder GUI from another class which also contains a JFrame - java

So I am working on a project that needs a GUI; currently, I have a class which creates a JFrame with a flock of agents in it and these agents fly around the environment. I need to add a GUI to this JFrme so I can control the size of the flock as well as other items.
I am using WindowBuilder in eclipse to create the GUI and I need to now 'attach' this GUI to the frame in the other class or, at the very least, have this GUI window running simultaneously with the other class so that when I run the application in eclipse, I can use the sliders to control the flock size then run the flock simulation, taking in the variable from the GUI.
I have been searching around online for quite some time trying to figure out how on earth to do this but I haven't been able to find an answer.
Code for Emre -> Thanks for the help so far! I have managed to get everything working regarding the JPanel but I am still having issues regarding the actionlistener for the "Run" button...I have included the amended code which contains an actionlistener for btnRun in the main class "Boids" - to me it looks like everything is correct and when run is pressed it should perform as expected but for whatever reason this button still isn't functional and I can't figure out why...
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.*;
import static java.lang.Math.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.*;
import javax.swing.Timer;
import java.util.Random;
import javax.swing.JButton;
public class Boids extends JPanel {
Flock flock;
Flock flock2;
final int w, h;
public Boids() {
w = 1200;
h = 600;
setPreferredSize(new Dimension(w, h));
setBackground(Color.black);
spawnFlock();
spawnFlock2();
new Timer(17, (ActionEvent e) -> {
if (flock.hasLeftTheBuilding(w))
spawnFlock();
repaint();
}).start();
new Timer(18, (ActionEvent e) -> {
if (flock2.hasLeftTheBuilding(w) && (flock.hasLeftTheBuilding(w)))
spawnFlock2();
repaint();
}).start();
//need to wait for the rest of the flock to leavebuilding before respawning leader, spawning is out of sync
}
public void spawnFlock() {
Random rand = new Random();
int n = rand.nextInt(599) + 1;
//implement random for width as well as height
flock = Flock.spawn(100, h - n, 20);
flock2 = Flock.spawn(100, h - n, 1);
}
public void spawnFlock2() {
Random rand = new Random();
int n = rand.nextInt(599) + 1;
//implement random for width as well as height
// flock2 = Flock.spawn(100, h - n, 1);
}
#Override
public void paintComponent(Graphics gg) {
super.paintComponent(gg);
Graphics2D g = (Graphics2D) gg;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
SimGUI buttonx = new SimGUI();
buttonx.btnRun.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event1) {
flock.run(g, w, h);
}
});
// flock.
// flock2.run(g, w, h);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("Simulator v0.6");
f.setResizable(false);
f.add(new Boids(), BorderLayout.CENTER);
// f.add(new Boids(), BorderLayout.CENTER); to add another flock to environment
//leaders will also be added in this fashion
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
// SimGUI.getFrames();
// SimGUI test = new SimGUI();
// test.panel.setVisible(true);
SimGUI test = new SimGUI();
f.getContentPane().add(test, BorderLayout.EAST); //just positions a slither to the right, dont understand why it wont display jpanel -->
//COULD THIS BE BECAUSE OF ME SETTING PREFERRED SIZE AND WIDTH/HEIGHT OUTSIDE OF MAIN? SEE "public Boids"...
//SimGUI tempt = new SimGUI();
// tempt.setVisible(true);
});
}
// private void printPanelCompPoints(JPanel f) {
// f.getComponentAt(600, 500);
//currently working on this = voting system
//see psuedocode!
}
//}
class Boid {
static final Random r = new Random();
static final Vec migrate = new Vec(0.02, 0);
static final int size = 3;
static final Path2D shape = new Path2D.Double();
static {
shape.moveTo(0, -size * 2);
shape.lineTo(-size, size * 2);
shape.lineTo(size, size * 2);
shape.closePath();
}
final double maxForce, maxSpeed;
Vec location, velocity, acceleration;
private boolean included = true;
Boid(double x, double y) {
acceleration = new Vec();
velocity = new Vec(r.nextInt(3) + 1, r.nextInt(3) - 1);
location = new Vec(x, y);
maxSpeed = 3.0;
maxForce = 0.05;
}
void update() {
velocity.add(acceleration);
velocity.limit(maxSpeed);
location.add(velocity);
acceleration.mult(0);
}
void applyForce(Vec force) {
acceleration.add(force);
}
Vec seek(Vec target) {
Vec steer = Vec.sub(target, location);
steer.normalize();
steer.mult(maxSpeed);
steer.sub(velocity);
steer.limit(maxForce);
return steer;
}
void flock(Graphics2D g, List<Boid> boids) {
view(g, boids);
Vec rule1 = separation(boids);
Vec rule2 = alignment(boids);
Vec rule3 = cohesion(boids);
rule1.mult(2.5);
rule2.mult(1.5);
rule3.mult(1.3);
applyForce(rule1);
applyForce(rule2);
applyForce(rule3);
applyForce(migrate);
}
void view(Graphics2D g, List<Boid> boids) {
double sightDistance = 100;
double peripheryAngle = PI * 0.85;
for (Boid b : boids) {
b.included = false;
if (b == this)
continue;
double d = Vec.dist(location, b.location);
if (d <= 0 || d > sightDistance)
continue;
Vec lineOfSight = Vec.sub(b.location, location);
double angle = Vec.angleBetween(lineOfSight, velocity);
if (angle < peripheryAngle)
b.included = true;
}
}
Vec separation(List<Boid> boids) {
double desiredSeparation = 25;
Vec steer = new Vec(0, 0);
int count = 0;
for (Boid b : boids) {
if (!b.included)
continue;
double d = Vec.dist(location, b.location);
if ((d > 0) && (d < desiredSeparation)) {
Vec diff = Vec.sub(location, b.location);
diff.normalize();
diff.div(d); // weight by distance
steer.add(diff);
count++;
}
}
if (count > 0) {
steer.div(count);
}
if (steer.mag() > 0) {
steer.normalize();
steer.mult(maxSpeed);
steer.sub(velocity);
steer.limit(maxForce);
return steer;
}
return new Vec(0, 0);
}
Vec alignment(List<Boid> boids) {
double preferredDist = 50;
Vec steer = new Vec(0, 0);
int count = 0;
for (Boid b : boids) {
if (!b.included)
continue;
double d = Vec.dist(location, b.location);
if ((d > 0) && (d < preferredDist)) {
steer.add(b.velocity);
count++;
}
}
if (count > 0) {
steer.div(count);
steer.normalize();
steer.mult(maxSpeed);
steer.sub(velocity);
steer.limit(maxForce);
}
return steer;
}
Vec cohesion(List<Boid> boids) {
double preferredDist = 50;
Vec target = new Vec(0, 0);
int count = 0;
for (Boid b : boids) {
if (!b.included)
continue;
double d = Vec.dist(location, b.location);
if ((d > 0) && (d < preferredDist)) {
target.add(b.location);
count++;
}
}
if (count > 0) {
target.div(count);
return seek(target);
}
return target;
}
/* Vec avoid(List<Boid> boids) {
int up = 0;
int down = 0;
for (Boid b : boids) {
if (b.location.x + 100 > 600 ) {
up = 1;
}
}
return velocity = new Vec (0,1);
} */
void draw(Graphics2D g) {
AffineTransform save = g.getTransform();
g.translate(location.x, location.y);
g.rotate(velocity.heading() + PI / 2);
g.setColor(Color.green);
g.fill(shape);
g.setColor(Color.green);
g.draw(shape);
g.setTransform(save);
g.drawOval(600, 500, 75, 75);
}
void run(Graphics2D g, List<Boid> boids, int w, int h) { //similair method to run leader
flock(g, boids);
update();
draw(g);
//may need additional run method for leader
}
}
class Flock {
List<Boid> boids;
Flock() {
boids = new ArrayList<>();
}
void run(Graphics2D g, int w, int h) {
for (Boid b : boids) {
b.run(g, boids, w, h);
}
}
boolean hasLeftTheBuilding(int w) {
int count = 0;
for (Boid b : boids) {
if (b.location.x + Boid.size > w) //will also be used to calculate votes based on whether boids is near food
count++;
}
return boids.size() == count;
}
void addBoid(Boid b) {
boids.add(b);
}
static Flock spawn(double w, double h, int numBoids) {
Flock flock = new Flock();
for (int i = 0; i < numBoids; i++)
flock.addBoid(new Boid(w, h));
return flock;
}
}
class Vec {
double x, y;
Vec() {
}
Vec(double x, double y) {
this.x = x;
this.y = y;
}
void add(Vec v) {
x += v.x;
y += v.y;
}
void sub(Vec v) {
x -= v.x;
y -= v.y;
}
void div(double val) {
x /= val;
y /= val;
}
void mult(double val) {
x *= val;
y *= val;
}
double mag() {
return sqrt(pow(x, 2) + pow(y, 2));
}
double dot(Vec v) {
return x * v.x + y * v.y;
}
void normalize() {
double mag = mag();
if (mag != 0) {
x /= mag;
y /= mag;
}
}
void limit(double lim) {
double mag = mag();
if (mag != 0 && mag > lim) {
x *= lim / mag;
y *= lim / mag;
}
}
double heading() {
return atan2(y, x);
}
static Vec sub(Vec v, Vec v2) {
return new Vec(v.x - v2.x, v.y - v2.y);
}
static double dist(Vec v, Vec v2) {
return sqrt(pow(v.x - v2.x, 2) + pow(v.y - v2.y, 2));
}
static double angleBetween(Vec v, Vec v2) {
return acos(v.dot(v2) / (v.mag() * v2.mag()));
}
Working JPanel! ->
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.util.Dictionary;
import java.util.Hashtable;
import javax.swing.JPanel;
import javax.swing.BoxLayout;
import javax.swing.JToolBar;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.RowSpec;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JSlider;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.Color;
import com.jgoodies.forms.layout.FormSpecs;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.ActionEvent;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.Font;
import javax.swing.JCheckBox;
import javax.swing.JTextField;
public class SimGUI extends JPanel {
/**
* Create the panel.
*/
//JPanel panel = new JPanel();
public JPanel panel_1 = new JPanel();
private JTextField textField;
private JTextField textField_1;
public JButton btnRun = new JButton("Run");
public SimGUI() {
JSlider sizeOfFlock = new JSlider();
sizeOfFlock.setValue(10);
sizeOfFlock.setMaximum(20);
sizeOfFlock.setMinimum(1);
JLabel lblNewLabel = new JLabel("Settings");
lblNewLabel.setFont(new Font("Sitka Banner", Font.BOLD, 18));
JLabel lblFlockSize = new JLabel("Flock Size");
lblFlockSize.setFont(new Font("Sitka Heading", Font.BOLD, 16));
JLabel label = new JLabel("1");
label.setFont(new Font("Sitka Display", Font.PLAIN, 14));
JLabel label_1 = new JLabel("20");
label_1.setFont(new Font("Sitka Display", Font.PLAIN, 14));
JLabel lblTypesOfLeader = new JLabel("Types of Leader:");
lblTypesOfLeader.setFont(new Font("Sitka Heading", Font.BOLD, 16));
JLabel lblNewLabel_1 = new JLabel("Spawn a leader inside the Flock");
lblNewLabel_1.setFont(new Font("Sitka Subheading", Font.PLAIN, 14));
JLabel lblSpawnAPersistant = new JLabel("Spawn a persistant leader");
lblSpawnAPersistant.setFont(new Font("Sitka Subheading", Font.PLAIN, 14));
JCheckBox checkBox = new JCheckBox("");
JCheckBox checkBox_1 = new JCheckBox("");
JSlider noOfRuns = new JSlider();
textField = new JTextField();
textField.setColumns(10);
textField.setText("" + noOfRuns.getValue());
textField_1 = new JTextField();
textField_1.setColumns(10);
textField_1.setText("" + sizeOfFlock.getValue());
/**
* Handle change event for sizeOfFlock slider.
*/
sizeOfFlock.addChangeListener(new ChangeListener(){
#Override
public void stateChanged(ChangeEvent e) {
textField_1.setText(String.valueOf(sizeOfFlock.getValue()));
}
});
textField_1.addKeyListener(new KeyAdapter(){
#Override
public void keyReleased(KeyEvent ke) {
String typed = textField_1.getText();
sizeOfFlock.setValue(0);
if(!typed.matches("\\d+") || typed.length() > 3) {
return;
}
int value = Integer.parseInt(typed);
sizeOfFlock.setValue(value);
}
});
/**
* Handle change event for noOfRuns slider.
*/
noOfRuns.addChangeListener(new ChangeListener(){
#Override
public void stateChanged(ChangeEvent e) {
textField.setText(String.valueOf(noOfRuns.getValue()));
}
});
textField.addKeyListener(new KeyAdapter(){
#Override
public void keyReleased(KeyEvent ke) {
String typed = textField.getText();
noOfRuns.setValue(0);
if(!typed.matches("\\d+") || typed.length() > 3) {
return;
}
int value = Integer.parseInt(typed);
noOfRuns.setValue(value);
}
});
JLabel label_2 = new JLabel("1");
label_2.setFont(new Font("Sitka Display", Font.PLAIN, 14));
JLabel label_3 = new JLabel("100");
label_3.setFont(new Font("Sitka Display", Font.PLAIN, 14));
JLabel lblNoOfSimulation = new JLabel("No. of runs");
lblNoOfSimulation.setFont(new Font("Sitka Heading", Font.BOLD, 16));
GroupLayout groupLayout = new GroupLayout(this);
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(83)
.addComponent(lblNewLabel)
.addGap(82)
.addComponent(panel_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addComponent(label, GroupLayout.PREFERRED_SIZE, 11, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(sizeOfFlock, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(label_1, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(textField_1, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE))
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addComponent(lblFlockSize)))
.addContainerGap())
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addComponent(lblNoOfSimulation)
.addContainerGap(207, Short.MAX_VALUE))
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addComponent(label_2, GroupLayout.PREFERRED_SIZE, 11, GroupLayout.PREFERRED_SIZE)
.addGap(2)
.addComponent(noOfRuns, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(label_3, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED, 10, Short.MAX_VALUE)
.addComponent(textField, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE)
.addGap(6))
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(lblTypesOfLeader)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(lblNewLabel_1)
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(checkBox_1, GroupLayout.PREFERRED_SIZE, 21, GroupLayout.PREFERRED_SIZE)
.addComponent(checkBox)))
.addComponent(lblSpawnAPersistant, GroupLayout.PREFERRED_SIZE, 178, GroupLayout.PREFERRED_SIZE))
.addContainerGap(53, Short.MAX_VALUE))
.addGroup(groupLayout.createSequentialGroup()
.addGap(86)
.addComponent(btnRun, GroupLayout.PREFERRED_SIZE, 76, GroupLayout.PREFERRED_SIZE)
.addContainerGap(136, Short.MAX_VALUE))
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.TRAILING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(5)
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(5)
.addComponent(panel_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGroup(groupLayout.createSequentialGroup()
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(lblNewLabel)))
.addPreferredGap(ComponentPlacement.RELATED, 8, Short.MAX_VALUE)
.addComponent(lblFlockSize)
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
.addComponent(label, GroupLayout.PREFERRED_SIZE, 34, GroupLayout.PREFERRED_SIZE)
.addComponent(sizeOfFlock, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(label_1, GroupLayout.PREFERRED_SIZE, 34, GroupLayout.PREFERRED_SIZE)
.addComponent(textField_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
.addGap(28)
.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(lblTypesOfLeader)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(lblNewLabel_1))
.addComponent(checkBox))
.addGap(11)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(lblSpawnAPersistant, GroupLayout.PREFERRED_SIZE, 19, GroupLayout.PREFERRED_SIZE)
.addComponent(checkBox_1, GroupLayout.PREFERRED_SIZE, 21, GroupLayout.PREFERRED_SIZE))
.addGap(30)
.addComponent(lblNoOfSimulation, GroupLayout.PREFERRED_SIZE, 21, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
.addComponent(noOfRuns, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(label_2, GroupLayout.PREFERRED_SIZE, 34, GroupLayout.PREFERRED_SIZE)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(label_3, GroupLayout.PREFERRED_SIZE, 34, GroupLayout.PREFERRED_SIZE)
.addComponent(textField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
.addGap(18)
.addComponent(btnRun, GroupLayout.PREFERRED_SIZE, 38, GroupLayout.PREFERRED_SIZE)
.addGap(225))
);
setLayout(groupLayout);
};
}
When the "Run" button is pressed it should execute flock.run(x,x,x) but despite my efforts this still wont perform as expected. I'm hoping you may be able to figure out why this is as I have been playing around with this for quite some time but have yet to get it working as expected

Make the GUI which you want to add to the JFrame a JPanel. Use it as a container to hold components you want to add to the GUI (buttons, labels, text areas etc.) After that call
frame.getContentPane().add(panel);
JFrame's default layout is border layout. So JPanel will be placed center by deafult if you do not modify default behaviour.
If you want to add more than one JPanel to the same JFrame, then you should explicitly specify which panel goes to which area like
frame.getContentPane().add(panel1, BorderLayout.CENTER);
frame.getContentPane().add(panel2, BorderLayout.LEFT);
If you do not specify layout area, only the last panel added will be visible at the center.
For more than one container, I suggest to use one JPanel as main container and set its layout accordingly. Next add other components to main JPanel and then add only that JPanel to JFrame.

Related

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

Putting an image in a Java GUI [duplicate]

This question already has answers here:
Adding images on Java JFrame - Netbeans
(3 answers)
Closed 6 years ago.
I'm creating a Java UI for a school project. I have 4 buttons and an image in the JFrame, I want to be able to perform a task on the Image with each button. Each time I press the button it will overwrite the Image using the buttons function. I have the buttons and functions working but I'm clueless at how to add the Image to the JFrame. Do I use a Jpanel or a canvas to put the image onto the frame. I used the netbeans GUI builder. Here is my code in a compressed form
//import static NewJFrame.plotWidth;
import ij.IJ;
import ij.ImagePlus;
import ij.WindowManager;
import ij.gui.GenericDialog;
import ij.process.ByteProcessor;
import ij.process.ColorProcessor;
import ij.process.ImageConverter;
import ij.process.ImageProcessor;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Polygon;
public class my_JframePlugin extends javax.swing.JFrame {
static int plotWidth =400;
static double angleInDegrees = 40;
static double angle = (angleInDegrees/360.0)*2.0*Math.PI;
static int polygonMultiplier = 100;
static boolean oneToOne;
double picsize;
ImagePlus img = IJ.openImage();
ImageProcessor imgP = img.getProcessor();
int[] x,y;
/**
* Creates new form NewJFrame
*/
public my_JframePlugin() {
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() {
jFileChooser1 = new javax.swing.JFileChooser();
canvas1 = new java.awt.Canvas();
jPanel1 = new javax.swing.JPanel();
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();
jButton3 = new javax.swing.JButton();
jButton4 = new javax.swing.JButton();
jButton5 = 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, 477, Short.MAX_VALUE)
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 310, Short.MAX_VALUE)
);
jButton1.setText("FFT");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
jButton2.setText("Inverse FFT");
jButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton2ActionPerformed(evt);
}
});
jButton3.setText("3D Plot");
jButton3.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton3ActionPerformed(evt);
}
});
jButton4.setText("Crop");
jButton4.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton4ActionPerformed(evt);
}
});
jButton5.setText("Add Image");
jButton5.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton5ActionPerformed(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()
.addGap(36, 36, 36)
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 28, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(jButton5, javax.swing.GroupLayout.DEFAULT_SIZE, 113, Short.MAX_VALUE)
.addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jButton2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jButton3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jButton4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGap(108, 108, 108))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(45, 45, 45)
.addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(31, 31, 31)
.addComponent(jButton2, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(33, 33, 33)
.addComponent(jButton3, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 42, Short.MAX_VALUE)
.addComponent(jButton4, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(38, 38, 38)
.addComponent(jButton5, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(56, 56, 56))
.addGroup(layout.createSequentialGroup()
.addGap(35, 35, 35)
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
IJ.log("FFT clicked");
}
private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
}
private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
}
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
//ImagePlus myimage = img;
img = WindowManager.getCurrentImage();
if (img==null)
{
//IJ.noImage();
IJ.log("No Image selected");
return;
}
if (!showDialog())
return;
if (img.getType()!=ImagePlus.GRAY8)
{
ImageProcessor ip = img.getProcessor();
ip = ip.crop(); // duplicate
img = new ImagePlus("temp", ip);
new ImageConverter(img).convertToGray8();
}
ImageProcessor plot = makeSurfacePlot(img.getProcessor());
new ImagePlus("Surface Plot", plot).show();
IJ.register(Surface_Plotter.class);
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
IJ.log("Inverse FFT clicked");
}
boolean showDialog()
{
GenericDialog gd = new GenericDialog("Surface Plotter");
gd.addNumericField("Width (pixels):", plotWidth, 0);
gd.addNumericField("Angle (-90-90 degrees):", angleInDegrees, 0);
gd.addNumericField("Polygon Multiplier (10-200%):", polygonMultiplier, 0);
gd.addCheckbox("One Polygon Per Line", oneToOne);
gd.showDialog();
if (gd.wasCanceled())
return false;
plotWidth = (int) gd.getNextNumber();
angleInDegrees = gd.getNextNumber();
polygonMultiplier = (int)gd.getNextNumber();
oneToOne = gd.getNextBoolean();
if (polygonMultiplier>400) polygonMultiplier = 400;
if (polygonMultiplier<10) polygonMultiplier = 10;
return true;
}
public ImageProcessor makeSurfacePlot(ImageProcessor ip)
{
double angle = (angleInDegrees/360.0)*2.0*Math.PI;
int polygons = (int)(plotWidth*(polygonMultiplier/100.0)/4);
if (oneToOne)
polygons = ip.getHeight();
double xinc = 0.8*plotWidth*Math.sin(angle)/polygons;
double yinc = 0.8*plotWidth*Math.cos(angle)/polygons;
boolean smooth = true;
IJ.showProgress(0.01);
ip.setInterpolate(true);
ip = ip.resize(plotWidth, polygons);
int width = ip.getWidth();
int height = ip.getHeight();
double min = ip.getMin();
double max = ip.getMax();
if (smooth)
ip.smooth();
//new ImagePlus("Image", ip).show();
int windowWidth =(int)(plotWidth+polygons*Math.abs(xinc) + 20.0);
int windowHeight = (int)(255+polygons*yinc + 10.0);
Image plot =IJ.getInstance().createImage(windowWidth, windowHeight);
Graphics g = plot.getGraphics();
g.setColor(Color.white);
g.fillRect(0, 0, windowWidth, windowHeight);
x = new int[width+2];
y = new int[width+2];
double xstart = 10.0;
if (xinc<0.0)
xstart += Math.abs(xinc)*polygons;
double ystart = 0.0;
for (int row=0; row<height; row++) {
double[] profile = ip.getLine(0, row, width-1, row);
Polygon p = makePolygon(profile, xstart, ystart);
g.setColor(Color.white);
g.fillPolygon(p);
g.setColor(Color.black);
g.drawPolygon(p);
xstart += xinc;
ystart += yinc;
if ((row%5)==0) IJ.showProgress((double)row/height);
}
IJ.showProgress(1.0);
ip = new ColorProcessor(plot);
byte[] bytes = new byte[windowWidth*windowHeight];
int[] ints =(int[]) ip.getPixels();
for (int i=0; i<windowWidth*windowHeight; i++)
bytes[i] = (byte)ints[i];
ip = new ByteProcessor(windowWidth,windowHeight, bytes, null);
return ip;
}
Polygon makePolygon(double[] profile, double xstart, double ystart) {
int width = profile.length;
for (int i=0; i<width; i++)
x[i] =(int)( xstart+i);
for (int i=0; i<width; i++)
y[i] =(int)(ystart+255.0-profile[i]);
x[width] =(int)xstart+width-1;
y[width] = (int)ystart+255;
x[width+1] =(int)xstart;
y[width+1] = (int)ystart+255;
//for (int i=0; i<width; i++)
// IJ.write("dbg: "+i+" "+profile[i]+" "+x[i]+" "+y[i]);
return new Polygon(x, y, width+2);
}
/**
* #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(my_JframePlugin.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(my_JframePlugin.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(my_JframePlugin.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(my_JframePlugin.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 NewJFrame().setVisible(true);
}
});
}
// Variables declaration - do not modify
private java.awt.Canvas canvas1;
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JButton jButton3;
private javax.swing.JButton jButton4;
private javax.swing.JButton jButton5;
private javax.swing.JFileChooser jFileChooser1;
private javax.swing.JPanel jPanel1;
// End of variables declaration
}
I just have no idea how to approach loading the image onto the frame
See the section from the Swing tutorial on How to Use Icons.
It shows you how to read an Image and use a JLabel to display the Image as an Icon.
The tutorial will also show you other Swing basics.

Exception in thread "main" java.lang.UnsatisfiedLinkError: org.opencv.objdetect.CascadeClassifier.CascadeClassifier_1(Ljava/lang/String;)J

Hey guys I've tried all the search, so obviously google doesn't help me ^^
I'm sure, that I've installed the opencv Library right, because the thing worked with earlier prototypes. All I've done is that I changed the main method a bit, so please keep close tabs on this. Function of the program: It streams from the webcam, gets the middle of the head and draw a path which follows your head.
Error: Exception in thread "main" java.lang.UnsatisfiedLinkError: org.opencv.objdetect.CascadeClassifier.CascadeClassifier_1(Ljava/lang/String;)J
at org.opencv.objdetect.CascadeClassifier.CascadeClassifier_1(Native Method)
at org.opencv.objdetect.CascadeClassifier.<init>(CascadeClassifier.java:58)
at at.htlklu.tremoranalyzer.FaceDetector.<init>(FaceDetector.java:17)
at at.htlklu.tremoranalyzer.Main.initComponents(Main.java:110)
at at.htlklu.tremoranalyzer.Main.<init>(Main.java:40)
at at.htlklu.tremoranalyzer.Main.main(Main.java:198)
//Main method
package at.htlklu.tremoranalyzer;
//In diesem Zwischenschritt vom TremorAnalyzer funktioniert das Zeichnen
//im Panel mit Linien, dem gelben Punkt und das Rechteck
//um das Gesicht.
//Screenshot im Matura Ordner Screenshots.
//Datum: 4.11.2014
//------------------------
//Update: 3 Buttons die funktionieren
//Datum 7.11.2014
import java.awt.*;
import javax.swing.*;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.highgui.VideoCapture;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JFrame;
import javax.swing.LayoutStyle.ComponentPlacement;
public class Main {
private FaceDetector faceDetector;
private Frame frame;
private static FacePanelX facePanel;
public static boolean state = true;
public Main(){
initComponents();
initCamera();
initProcessing();
}
private void initProcessing() {
VideoCapture webCam = new VideoCapture(0);
Mat webcam_image = new Mat();
if (webCam.isOpened()) {
try {
Thread.sleep(500);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while (state) {
webCam.read(webcam_image);
if (!webcam_image.empty()) {
try {
Thread.sleep(200);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
frame.setSize(webcam_image.width() +40 ,
webcam_image.height() +80 );
webcam_image = faceDetector.detect(webcam_image);
// Display the image
facePanel.matToBufferedImage(webcam_image);
Point center = faceDetector.getCenter();
if (center != null) {
facePanel.setFaceCenter(center);
facePanel.repaint();
facePanel.invalidate();
}
} else {
System.out.println(" --(!) No captured frame from webcam !");
webCam.release();
break;
}
}
}
webCam.release();
}
private void initCamera() {
}
private void initComponents() {
frame = new JFrame("WebCam Capture - Face detection");
((JFrame) frame).setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
faceDetector = new FaceDetector();
frame.setSize(400, 400); // give the frame some size
frame.setBackground(Color.BLUE);
JButton btnExit = new JButton("Exit");
btnExit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
JButton btnStopRecord = new JButton("Stop Recording");
btnStopRecord.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
state = false;
}
});
JButton btndrawLine = new JButton("Draw Path");
btndrawLine.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
facePanel.getArray().clear();
drawLine();
}
});
GroupLayout groupLayout = new GroupLayout(((JFrame) frame).getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(facePanel, GroupLayout.DEFAULT_SIZE, 388, Short.MAX_VALUE)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(btnExit, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(37)
.addComponent(btnStopRecord, GroupLayout.DEFAULT_SIZE, 139, Short.MAX_VALUE)
.addGap(30)
.addComponent(btndrawLine, GroupLayout.DEFAULT_SIZE, 107, Short.MAX_VALUE)))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.TRAILING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addComponent(facePanel, GroupLayout.DEFAULT_SIZE, 331, Short.MAX_VALUE)
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(btnExit, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btndrawLine, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnStopRecord, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
);
((JFrame) frame).getContentPane().setLayout(groupLayout);
frame.setVisible(true);
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Throwable e) {
e.printStackTrace();
}
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
facePanel = new FacePanelX();
}
public static void main(String arg[]) throws InterruptedException {
Main m = new Main();
}
private static void drawLine(){
facePanel.setDrawLineActive(!facePanel.isDrawLineActive());
}
}
//FacePanelX for drawing
package at.htlklu.tremoranalyzer;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.Point;
import org.opencv.highgui.Highgui;
public class FacePanelX extends JPanel {
private BufferedImage image;
private boolean drawLineActive = false;
private ArrayList<Point> array = new ArrayList<Point>();
private Point faceCenter = new Point();
//---------------------------------------------------------------------------------------------------------------
// getters, setters
public ArrayList<Point> getArray() {
return array;
}
public void setArray(ArrayList<Point> array) {
this.array = array;
}
public Point getFaceCenter() {
return faceCenter;
}
public void setFaceCenter(Point point) {
this.faceCenter = point;
array.add(point);
}
// \getters, setters
//---------------------------------------------------------------------------------------------------------------
public FacePanelX() {
super();
}
//---------------------------------------------------------------------------------------------------------------
public boolean matToBufferedImage(Mat matrix) {
MatOfByte mb = new MatOfByte();
Highgui.imencode(".jpg", matrix, mb);
try {
this.image = ImageIO.read(new ByteArrayInputStream(mb.toArray()));
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
// \ matToBufferedImage
//---------------------------------------------------------------------------------------------------------------
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (this.image == null)
return;
g2d.drawImage(this.image, 10, 10, this.image.getWidth(),
this.image.getHeight(), null);
drawFaceRect(g2d);
drawMiddle(g2d);
if(drawLineActive)
drawLine(g2d);
g2d.dispose();
}
// \ paintComponent
//---------------------------------------------------------------------------------------------------------------
public void drawFaceRect(Graphics2D g) {
g.setColor(Color.blue);
g.drawRect(((int) faceCenter.x - 31), (int) faceCenter.y - 31, 62, 62);
}
public void drawMiddle(Graphics2D g) {
g.setColor(Color.ORANGE);
g.fillOval(1280 / 2, 720 / 2, 10, 10);
}
// \ drawRect, drawMiddle
//---------------------------------------------------------------------------------------------------------------
public void drawLine(Graphics2D g) {
// state = false;
// if (!((int) faceCenter.x > 350 && (int) faceCenter.y > 280)
// || ((int) faceCenter.x < 280 && (int) faceCenter.y < 190)) {
// state = true;
// }
Point bufP = new Point(-1, -1);
g.setColor(Color.blue);
if (array.size() > 1) {
for (Point p : array) {
System.out.println("p: " + p.x + " " + p.y);
g.fillOval((int) p.x, (int) p.y, 2, 2);
if (!(bufP.x == -1 && bufP.y == -1)) {
g.drawLine((int) bufP.x, (int) bufP.y, (int) p.x, (int) p.y);
}
bufP.x = p.x;
bufP.y = p.y;
}
}
}
// \ methode drawLine
//---------------------------------------------------------------------------------------------------------------
public boolean isDrawLineActive() {
return drawLineActive;
}
public void setDrawLineActive(boolean drawLineActive) {
this.drawLineActive = drawLineActive;
}
}
//FaceDetector for CascadeClassifier
package at.htlklu.tremoranalyzer;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
public class FaceDetector {
private CascadeClassifier faceCascade;
private Point center;
/**
*
*/
public FaceDetector() {
faceCascade = new CascadeClassifier("src/lbpcascade_frontalface.xml");
if (faceCascade.empty()) {
System.out.println("--(!)Error loading cascade classifier\n");
return;
} else {
System.out.println("Face classifier loaded up");
}
}
/**
* Does some basic preprocessing
*
* #param inputframe The frame to be processed
* #return The processed matrix
*/
public Mat detect(Mat inputframe) {
Mat mRgba = new Mat();
Mat mGrey = new Mat();
MatOfRect faces = new MatOfRect();
inputframe.copyTo(mRgba);
inputframe.copyTo(mGrey);
Imgproc.cvtColor(mRgba, mGrey, Imgproc.COLOR_BGR2GRAY);
Imgproc.equalizeHist(mGrey, mGrey);
faceCascade.detectMultiScale(mGrey, faces);
for (Rect rect : faces.toArray()) {
center = new Point(rect.x + rect.width * 0.5, rect.y + rect.height
* 0.5);
}
return mRgba;
}
// ---------------------------------------------------------------------------------------------------------------
public Point getCenter() {
return center;
}
}
// \class FaceDetector
// ---------------------------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------------------------

smooth rounded corners in swing

I want to make smooth rounded corners for my swing application, but I can't get my desired result...
here's the screenshots:
1.setShape() for JFrame :
2.overriding paintComponent() method for JPanel instead of using setShape() :
3.setBackground(new Color(0, 0, 0, 0)) for JFrame :
well, but there's a problem with text quality:
before step 3 :
after step 3 :
guys I'm confused, I've searched many times but nothing helped me...
what should I do? please help me
here's the full code :
public class WelcomePage extends JFrame {
private Point initialClick;
private boolean end = false;
private JLabel jLabelAppTitle;
private JPanel jPanelExit;
private JLabel jLabelHint;
private int r = 220, g = 0, b = 0;
private int r2 = 10, g2 = 10, b2 = 10;
private boolean flag = false;
public WelcomePage() {
initComponents();
// setShape(new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(), 15, 15));
centerLocation();
refreshPage();
}
public static void main(String args[]) {
try {
for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
EventQueue.invokeLater(() -> FadeTransitions.fadeIn(new WelcomePage(), FadeTransitions.NORMAL_FADE, true));
}
private void refreshPage() {
Timer timer = new Timer(20, e -> {
if (!end) {
if (r == 220 && b == 0 && g < 220) {
g++;
} else if (g == 220 && b == 0 && r > 0) {
r--;
} else if (g == 220 && r == 0 && b < 220) {
b++;
} else if (b == 220 && r == 0 && g > 0) {
g--;
} else if (b == 220 && g == 0 && r < 220) {
r++;
} else if (r == 220 && g == 0 && b > 0) {
b--;
}
if (!flag) {
r2 += 5;
g2 += 5;
b2 += 5;
if (r2 == 250) {
flag = true;
}
} else {
r2 -= 5;
g2 -= 5;
b2 -= 5;
if (r2 == 10) {
flag = false;
}
}
jLabelAppTitle.setForeground(new Color(r, g, b));
jLabelHint.setForeground(new Color(r2, g2, b2));
} else {
((Timer) e.getSource()).stop();
}
});
timer.setCoalesce(true);
timer.setRepeats(true);
timer.start();
}
private void centerLocation() throws HeadlessException {
final Toolkit toolkit = Toolkit.getDefaultToolkit();
final Dimension screenSize = toolkit.getScreenSize();
final int x = (screenSize.width - this.getWidth()) / 2;
final int y = (screenSize.height - this.getHeight()) / 2;
this.setLocation(x, y);
}
#SuppressWarnings("unchecked")
private void initComponents() {
JPanel jPanelMain = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
RenderingHints qualityHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
qualityHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHints(qualityHints);
g2.setPaint(Color.WHITE);
g2.fillRoundRect(0, 0, getWidth(), getHeight(), 25, 25);
g2.dispose();
}
};
jPanelExit = new JPanel();
JLabel jLabelExit = new JLabel();
JLabel jLabelWelcome = new JLabel();
jLabelAppTitle = new JLabel();
jLabelHint = new JLabel();
JButton jButtonGo = new JButton();
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
setTitle("welcome to My App!");
setUndecorated(true);
setBackground(new Color(0, 0, 0, 0));
addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
close();
}
});
addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
public void mouseDragged(MouseEvent evt) {
thisMouseDragged(evt);
}
});
addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(MouseEvent evt) {
thisMousePressed(evt);
}
});
jPanelMain.setBackground(Color.WHITE);
jPanelExit.setBackground(new Color(160, 0, 20));
jLabelExit.setFont(new Font("Tahoma", Font.BOLD, 13));
jLabelExit.setForeground(new Color(255, 255, 255));
jLabelExit.setHorizontalAlignment(SwingConstants.CENTER);
jLabelExit.setText("X");
jLabelExit.setCursor(new Cursor(Cursor.HAND_CURSOR));
jLabelExit.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(MouseEvent evt) {
jLabelExitMouseClicked();
}
public void mouseEntered(MouseEvent evt) {
jLabelExitMouseEntered();
}
public void mouseExited(MouseEvent evt) {
jLabelExitMouseExited();
}
});
GroupLayout jPanelExitLayout = new GroupLayout(jPanelExit);
jPanelExit.setLayout(jPanelExitLayout);
jPanelExitLayout.setHorizontalGroup(
jPanelExitLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addGroup(GroupLayout.Alignment.TRAILING, jPanelExitLayout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(jLabelExit, GroupLayout.PREFERRED_SIZE, 45, GroupLayout.PREFERRED_SIZE))
);
jPanelExitLayout.setVerticalGroup(
jPanelExitLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addGroup(GroupLayout.Alignment.TRAILING, jPanelExitLayout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(jLabelExit, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE))
);
jLabelWelcome.setFont(new Font("Tahoma", 0, 25));
jLabelWelcome.setForeground(new Color(0, 0, 100));
jLabelWelcome.setHorizontalAlignment(SwingConstants.CENTER);
jLabelWelcome.setText("Welcome");
jLabelAppTitle.setFont(new Font("MV Boli", 0, 29));
jLabelAppTitle.setHorizontalAlignment(SwingConstants.CENTER);
jLabelAppTitle.setText("My Swing App");
jButtonGo.setBackground(new Color(100, 20, 80));
jButtonGo.setFont(new Font("Tahoma", 0, 15));
jButtonGo.setForeground(new Color(255, 255, 255));
jButtonGo.setText("GO");
jButtonGo.addActionListener(evt -> jButtonGoActionPerformed());
jLabelHint.setFont(new Font("Tahoma", 0, 11));
jLabelHint.setHorizontalAlignment(SwingConstants.CENTER);
jLabelHint.setText("press GO button");
javax.swing.GroupLayout jPanelMainLayout = new javax.swing.GroupLayout(jPanelMain);
jPanelMain.setLayout(jPanelMainLayout);
jPanelMainLayout.setHorizontalGroup(
jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanelMainLayout.createSequentialGroup()
.addContainerGap(48, Short.MAX_VALUE)
.addGroup(jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelMainLayout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(jPanelExit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(15, 15, 15))
.addGroup(jPanelMainLayout.createSequentialGroup()
.addGroup(jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addComponent(jLabelWelcome, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jLabelAppTitle, javax.swing.GroupLayout.DEFAULT_SIZE, 220, Short.MAX_VALUE)
.addComponent(jLabelHint, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jButtonGo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap(48, Short.MAX_VALUE))))
);
jPanelMainLayout.setVerticalGroup(
jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanelMainLayout.createSequentialGroup()
.addComponent(jPanelExit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(64, 64, 64)
.addComponent(jLabelWelcome, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(98, 98, 98)
.addComponent(jLabelAppTitle)
.addGap(86, 86, 86)
.addComponent(jLabelHint)
.addGap(24, 24, 24)
.addComponent(jButtonGo, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(86, 86, 86))
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jPanelMain, javax.swing.GroupLayout.DEFAULT_SIZE, 316, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jPanelMain, javax.swing.GroupLayout.DEFAULT_SIZE, 473, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
pack();
}
private void thisMousePressed(MouseEvent evt) {
initialClick = evt.getPoint();
}
private void thisMouseDragged(MouseEvent evt) {
int thisX = this.getLocation().x;
int thisY = this.getLocation().y;
int xMoved = (thisX + evt.getX()) - (thisX + initialClick.x);
int yMoved = (thisY + evt.getY()) - (thisY + initialClick.y);
int x = thisX + xMoved;
int y = thisY + yMoved;
this.setLocation(x, y);
}
private void jLabelExitMouseClicked() {
close();
}
private void close() {
end = true;
FadeTransitions.fadeOut(this, FadeTransitions.FAST_FADE, FadeTransitions.EXIT_ON_CLOSE);
}
private void jLabelExitMouseEntered() {
jPanelExit.setBackground(new Color(200, 0, 20));
}
private void jLabelExitMouseExited() {
jPanelExit.setBackground(new Color(160, 0, 20));
}
private void jButtonGoActionPerformed() {
end = true;
FadeTransitions.run(this, new ServerManager(this), FadeTransitions.NORMAL_FADE, FadeTransitions.DISPOSE_ON_CLOSE);
}
}
thanks.
Sorry, not an answer, but hopefully at least one step towards an acceptable answer: From my analysis so far, it might be that this is simply a bug somewhere deep (deeeep!) inside the rendering pipeline.
The following MVCE shows two (undecorated) frames, each containing a button. They are equal, except for the background of the frames. For one frame, the color is transparent, and for the other one, it is opaque.
import java.awt.Color;
import java.awt.Font;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class TextRenderBug extends JFrame {
public static void main(String[] args)
{
setLookAndFeel();
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
createAndShowGUI(new Color(0,0,0 ), 400);
createAndShowGUI(new Color(0,0,0,0), 600);
}
});
}
private static void setLookAndFeel()
{
try
{
for (UIManager.LookAndFeelInfo info :
UIManager.getInstalledLookAndFeels())
{
if ("Nimbus".equals(info.getName()))
{
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
private static void createAndShowGUI(Color background, int x)
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setUndecorated(true);
f.setBackground(background);
JButton b = new JButton("Text");
b.setFont(new Font("Tahoma", 0, 15));
f.getContentPane().add(b);
f.setBounds(x, 400, 200, 50);
f.setVisible(true);
}
}
It clearly shows that the text is rendered differently, solely depending on the background being transparent - and of course, this should not be the case.
(This is not Nimbus-specific, by the way: It also applies to other LookAndFeels. Just remove the line where the LaF is set).
What I found out so far:
The behavior is somehow caused by the drawString method of the sun.swing.SwingUtilities2 class
It does not appear in all components. It can be observed on JButton and JLabel, but not on a normal JComponent
Update: It also does not depend on the font (although with other fonts, the effect is not so noticable). When rendered correctly, the font looks a little bit more bold, but of course, it is not simply the same font as a Font.BOLD.
The painting process is rather complicated.
(OK, some of you might already have known the latter).
Here is an example that shows the last observations, maybe it can serve as a starting point for further research of others:
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.lang.reflect.Method;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class TextRenderBugTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
createAndShowGUI(new Color(0,0,0 ), 400);
createAndShowGUI(new Color(0,0,0,0), 600);
}
});
}
private static void createAndShowGUI(Color background, int x)
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setUndecorated(true);
f.setBackground(background);
JButton b = new JButton("Text");
b.setFont(new Font("Tahoma", 0, 15));
JComponent c = new ExampleComponent();
c.setFont(new Font("Tahoma", 0, 15));
f.getContentPane().setLayout(new GridLayout(0,1));
f.getContentPane().add(b);
f.getContentPane().add(c);
f.setBounds(x, 400, 200, 100);
f.setVisible(true);
}
static class ExampleComponent
//extends JComponent
extends JButton
{
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(getForeground());
g.drawString("Text", 10, 20);
drawStringWithSwingUtilities(g, 60, 20);
}
private void drawStringWithSwingUtilities(Graphics g, int x, int y)
{
try
{
Class<?> c = Class.forName("sun.swing.SwingUtilities2");
Method m = c.getMethod("drawString", JComponent.class,
Graphics.class, String.class, int.class, int.class);
m.invoke(null, this, g, "Text", x, y);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
I already tried to analyze this further, and played around with RenderingHints like KEY_TEXT_ANTIALIASING and KEY_TEXT_LCD_CONTRAST and other settings that are changed in the painting pipeline while it is heading towards the pixels that are finally placed on the screen, but no further insights until now.
(If you want to, you can add this information to your original question, then I'll delete this (not-)answer)
The only chance you have is working with regions. You will need to hardcode a bit and play with subtract, but eventually it will look fine. You can take a look at how it's done in mylyn's notification class: http://grepcode.com/file/repository.grepcode.com/java/eclipse.org/3.6/org.eclipse.mylyn.commons/ui/3.4.0/org/eclipse/mylyn/internal/provisional/commons/ui/AbstractNotificationPopup.java
Hope it helps, best of luck!
Edit: Just remembered this little tutorial which might help: http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/SWTShellcreateanonrectangularwindow.htm

Resize the panel without revalidation

I have aJPanel in which I draw lines to create an illusion of pencil. This panel is in aScrollPane.
When I resize the panel one call to revalidate() method is automatically placed and all my drawn lines in this panel are gone. Is there any way to keep my drawn line in the panel with the new size ?
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
*
* #author Sanjeev
*/
public class WorkArea extends JFrame implements ActionListener, MouseListener, MouseMotionListener
{
private final int PEN_OP = 1;
private final int ERASER_OP = 2;
private final int SCROLL_OP = 3;
private int mousex = 0;
private int mousey = 0;
private int prevx = 0;
private int prevy = 0;
private boolean initialPen = true;
private boolean initialEraser = true;
private int eraserLength = 5;
private int opStatus = PEN_OP;
private Color mainColor = new Color(0,0,0);
private int drawPanelHeight =1000;
public WorkArea()
{
initComponents();
setLocationRelativeTo(null);
pencilButton.addActionListener(this);
eraserButton.addActionListener(this);
drawPanel.addMouseMotionListener(this);
drawPanel.addMouseListener(this);
drawPanel.add(new TestPane());
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
private void initComponents() {
headerPanel = new javax.swing.JPanel();
backButton = new javax.swing.JLabel();
headerImage = new javax.swing.JLabel();
controlPanel = new javax.swing.JPanel();
scrollButton = new javax.swing.JButton();
pencilButton = new javax.swing.JButton();
eraserButton = new javax.swing.JButton();
drawingPanel = new javax.swing.JPanel();
drawingScrollPane = new javax.swing.JScrollPane();
drawPanel = new javax.swing.JPanel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("v0.1");
setBackground(new java.awt.Color(237, 254, 255));
setBounds(new java.awt.Rectangle(0, 0, 513, 693));
setResizable(false);
headerPanel.setBackground(new java.awt.Color(237, 254, 255));
headerPanel.setPreferredSize(new java.awt.Dimension(513, 25));
headerPanel.setLayout(null);
backButton.setBackground(new java.awt.Color(237, 254, 255));
backButton.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
backButton.setForeground(new java.awt.Color(255, 255, 255));
backButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/back-arrow.png"))); // NOI18N
backButton.setText("Back");
backButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
backButton.setPreferredSize(new java.awt.Dimension(40, 20));
headerPanel.add(backButton);
backButton.setBounds(0, 3, 40, 20);
headerImage.setBackground(new java.awt.Color(237, 254, 255));
headerImage.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N
headerImage.setForeground(new java.awt.Color(255, 255, 255));
headerImage.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/topbar_ipad_wide.png"))); // NOI18N
headerImage.setText("Work Area");
headerImage.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
headerImage.setPreferredSize(new java.awt.Dimension(513, 25));
headerPanel.add(headerImage);
headerImage.setBounds(0, 0, 513, 25);
controlPanel.setBackground(new java.awt.Color(237, 254, 255));
controlPanel.setPreferredSize(new java.awt.Dimension(90, 670));
controlPanel.setLayout(null);
scrollButton.setBackground(new java.awt.Color(237, 254, 255));
scrollButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/up_down_ipad.png"))); // NOI18N
scrollButton.setPreferredSize(new java.awt.Dimension(60, 60));
scrollButton.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
scrollButtonMouseClicked(evt);
}
});
controlPanel.add(scrollButton);
scrollButton.setBounds(20, 570, 60, 60);
pencilButton.setBackground(new java.awt.Color(237, 254, 255));
pencilButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/pencil_ipad.png"))); // NOI18N
pencilButton.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
pencilButtonMouseClicked(evt);
}
});
controlPanel.add(pencilButton);
pencilButton.setBounds(20, 450, 60, 60);
eraserButton.setBackground(new java.awt.Color(237, 254, 255));
eraserButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/eraser_ipad.png"))); // NOI18N
eraserButton.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
eraserButtonMouseClicked(evt);
}
});
controlPanel.add(eraserButton);
eraserButton.setBounds(20, 510, 60, 60);
drawingPanel.setBackground(new java.awt.Color(237, 254, 255));
drawingPanel.setPreferredSize(new java.awt.Dimension(420, 670));
drawingPanel.setLayout(null);
drawingScrollPane.setBorder(null);
drawingScrollPane.setPreferredSize(new java.awt.Dimension(423, 1000));
drawPanel.setBackground(new java.awt.Color(237, 254, 255));
drawPanel.setPreferredSize(new java.awt.Dimension(400, 1000));
drawPanel.setLayout(null);
drawingScrollPane.setViewportView(drawPanel);
drawingPanel.add(drawingScrollPane);
drawingScrollPane.setBounds(0, 0, 424, 670);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 513, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(headerPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 513, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(controlPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 423, Short.MAX_VALUE)))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 93, Short.MAX_VALUE)
.addComponent(drawingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 420, javax.swing.GroupLayout.PREFERRED_SIZE)))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 693, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(headerPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 668, Short.MAX_VALUE)))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 23, Short.MAX_VALUE)
.addComponent(controlPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 670, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 23, Short.MAX_VALUE)
.addComponent(drawingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 670, javax.swing.GroupLayout.PREFERRED_SIZE)))
);
pack();
}
#Override
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand() == "Pen")
opStatus = PEN_OP;
if (e.getActionCommand() == "Eraser")
opStatus = ERASER_OP;
if(e.getActionCommand() == "Scroll")
opStatus = SCROLL_OP;
}
private void pencilButtonMouseClickedTest(java.awt.event.MouseEvent evt)
{
opStatus = PEN_OP;
Graphics g = drawPanel.getGraphics();
if (initialPen)
{
setGraphicalDefaults(evt);
initialPen = false;
g.drawLine(prevx,prevy,mousex,mousey);
}
if (mouseHasMoved(evt))
{
mousex = evt.getX();
mousey = evt.getY();
g.drawLine(prevx,prevy,mousex,mousey);
prevx = mousex;
prevy = mousey;
}
}
private void eraserButtonMouseClickedTest(java.awt.event.MouseEvent evt)
{
opStatus = ERASER_OP;
Graphics g = drawPanel.getGraphics();
if (initialEraser)
{
setGraphicalDefaults(evt);
initialEraser = false;
mousex = evt.getX();
mousey = evt.getY();
System.out.println("Initial Eraser ::::::::x's value is : "+prevx+" , "+mousey+" and y's value is : "+mousex+" , "+mousey);
g.setColor(new java.awt.Color(237,254,255));
g.fillRect(mousex-eraserLength, mousey-eraserLength,eraserLength*2,eraserLength*2);
//g.setColor(Color.black); //Eraser Border
g.drawRect(mousex-eraserLength,mousey-eraserLength,eraserLength*2,eraserLength*2);
prevx = mousex;
prevy = mousey;
}
if (mouseHasMoved(evt))
{
System.out.println("Eraser ::::::::x's value is : "+prevx+" , "+mousey+" and y's value is : "+mousex+" , "+mousey);
g.setColor(new java.awt.Color(237,254,255));
g.drawRect(prevx-eraserLength, prevy-eraserLength,eraserLength*2,eraserLength*2);
mousex = evt.getX();
mousey = evt.getY();
/* Draw eraser block to panel */
g.setColor(new java.awt.Color(237,254,255));
g.fillRect(mousex-eraserLength, mousey-eraserLength,eraserLength*2,eraserLength*2);
g.setColor(Color.black);//Eraser Border
g.drawRect(mousex-eraserLength,mousey-eraserLength,eraserLength*2,eraserLength*2);
prevx = mousex;
prevy = mousey;
}
}
private void scrollButtonMouseClicked(java.awt.event.MouseEvent evt) {
opStatus = SCROLL_OP;
drawingScrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
#Override
public void adjustmentValueChanged(AdjustmentEvent e)
{
int extent,curValue;
extent = drawingScrollPane.getVerticalScrollBar().getModel().getExtent();
curValue = drawingScrollPane.getVerticalScrollBar().getValue()+extent;
if(curValue==drawPanel.getHeight())
{
System.out.println("value of scroll equals to Max value....");
drawPanel.setPreferredSize(new Dimension(423,drawPanelHeight*4));
}
System.out.println("Value: " + curValue + " Max: " + drawingScrollPane.getVerticalScrollBar().getMaximum());
}
});
}
private void eraserButtonMouseClicked(java.awt.event.MouseEvent evt) {
eraserButtonMouseClickedTest(evt);
updateMouseCoordinates(evt);
}
private void pencilButtonMouseClicked(java.awt.event.MouseEvent evt) {
opStatus = PEN_OP;
}
public boolean mouseHasMoved(MouseEvent e)
{
return (mousex != e.getX() || mousey != e.getY());
}
public void setGraphicalDefaults(MouseEvent e)
{
mousex = e.getX();
mousey = e.getY();
prevx = e.getX();
prevy = e.getY();
}
#Override
public void mouseDragged(MouseEvent e)
{
updateMouseCoordinates(e);
switch (opStatus)
{
case PEN_OP : pencilButtonMouseClickedTest(e);
break;
case ERASER_OP: eraserButtonMouseClicked(e);
break;
case SCROLL_OP: scrollButtonMouseClicked(e);
break;
}
}
public void mouseReleased(MouseEvent e)
{
updateMouseCoordinates(e);
switch (opStatus)
{
case PEN_OP : releasedPen();
break;
case ERASER_OP : releasedEraser();
break;
}
}
public void mouseEntered(MouseEvent e)
{
updateMouseCoordinates(e);
}
public void releasedPen()
{
initialPen = true;
}
public void releasedEraser()
{
initialEraser = true;
Graphics g = drawPanel.getGraphics();
g.setColor(mainColor.white);
g.drawRect(mousex-eraserLength,mousey-eraserLength,eraserLength*2,eraserLength*2);
}
public void updateMouseCoordinates(MouseEvent e)
{
String xCoor ="";
String yCoor ="";
if (e.getX() < 0) xCoor = "0";
else
{
xCoor = String.valueOf(e.getX());
}
if (e.getY() < 0) xCoor = "0";
else
{
yCoor = String.valueOf(e.getY());
}
}
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(WorkArea.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(WorkArea.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(WorkArea.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(WorkArea.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new WorkArea().setVisible(true);
}
});
}
private javax.swing.JLabel backButton;
private javax.swing.JPanel controlPanel;
private javax.swing.JPanel drawPanel;
private javax.swing.JPanel drawingPanel;
private javax.swing.JScrollPane drawingScrollPane;
private javax.swing.JButton eraserButton;
private javax.swing.JLabel headerImage;
private javax.swing.JPanel headerPanel;
private javax.swing.JButton pencilButton;
private javax.swing.JButton scrollButton;
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
updateMouseCoordinates(e);
}
#Override
public void mouseMoved(MouseEvent e) {
updateMouseCoordinates(e);
}
#Override
public void mousePressed(MouseEvent e) {
updateMouseCoordinates(e);
}
}
I assume you are drawing to the JPanel by using getGraphics() and rendering your out put to it.
You have now seen why you shouldn't do this. When the component is repainted, anything previously painted to is wiped cleaned and you are expected to repaint the contents.
Start by overriding paintComponent and updating all the lines within this method (don't forget to call super.paintComponent
See Performing Custom Painting and Painting in AWT and Swing for more details
For example..
Drawing a rectangle that won't disappear in next paint
MouseEvent is not registering a release when I release the mouse button
Updated with example
This is a modified version of the answer to MouseEvent is not registering a release when I release the mouse button which includes a scroll pane...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
public class MouseDraggedTest {
public static void main(String[] args) {
new MouseDraggedTest();
}
public MouseDraggedTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(new TestPane()));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Map<Point, List<Point>> mapPoints;
private Point currentPoint;
public TestPane() {
mapPoints = new HashMap<>(25);
MouseAdapter mouseListener = new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
currentPoint = e.getPoint();
mapPoints.put(currentPoint, new ArrayList<Point>(25));
}
#Override
public void mouseReleased(MouseEvent e) {
List<Point> points = mapPoints.get(currentPoint);
if (points.isEmpty()) {
mapPoints.remove(currentPoint);
}
currentPoint = null;
}
#Override
public void mouseDragged(MouseEvent me) {
List<Point> points = mapPoints.get(currentPoint);
points.add(me.getPoint());
repaint();
}
};
addMouseListener(mouseListener);
addMouseMotionListener(mouseListener);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 800);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Point startPoint : mapPoints.keySet()) {
List<Point> points = mapPoints.get(startPoint);
for (Point p : points) {
if (startPoint != null) {
g.drawLine(startPoint.x, startPoint.y, p.x, p.y);
}
startPoint = p;
}
}
}
}
}
Updated with a BufferedImage example
Because you need to supply more operations than just drawing, you may find it easier to use BufferedImage as your primary drawing surface and render this to your DrawingPanel
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToggleButton;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MyPicture {
public static void main(String[] args) {
new MyPicture();
}
public MyPicture() {
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 TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public enum DrawOperation {
Draw,
Erase
}
public class TestPane extends JPanel {
private DrawOperation op;
private JToggleButton pencil;
private JToggleButton eraser;
private DrawPane drawPane;
public TestPane() {
setLayout(new BorderLayout());
drawPane = new DrawPane();
MouseAdapter adapter = new MouseAdapter() {
private Point startPoint;
#Override
public void mouseEntered(MouseEvent e) {
drawPane.updateDrawCursor(e.getPoint(), op);
}
#Override
public void mouseExited(MouseEvent e) {
drawPane.removeDrawCursor();
}
#Override
public void mousePressed(MouseEvent e) {
startPoint = e.getPoint();
}
#Override
public void mouseReleased(MouseEvent e) {
startPoint = null;
}
#Override
public void mouseDragged(MouseEvent e) {
drawPane.applyOperation(startPoint, e.getPoint(), op);
drawPane.updateDrawCursor(e.getPoint(), op);
startPoint = e.getPoint();
}
#Override
public void mouseMoved(MouseEvent e) {
drawPane.updateDrawCursor(e.getPoint(), op);
}
};
drawPane.addMouseListener(adapter);
drawPane.addMouseMotionListener(adapter);
JPanel operations = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
pencil = new JToggleButton("Draw");
eraser = new JToggleButton("Erase");
ButtonGroup bgOps = new ButtonGroup();
bgOps.add(pencil);
bgOps.add(eraser);
operations.add(pencil, gbc);
operations.add(eraser, gbc);
pencil.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
op = DrawOperation.Draw;
}
});
eraser.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
op = DrawOperation.Erase;
}
});
add(operations, BorderLayout.WEST);
add(new JScrollPane(drawPane));
}
}
public class DrawPane extends JPanel {
private BufferedImage image;
private Shape drawCursor;
private Point cursorPoint;
private int eraseSize = 20;
public DrawPane() {
image = new BufferedImage(400, 400, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
g2d.setBackground(Color.WHITE);
g2d.fillRect(0, 0, 400, 400);
g2d.dispose();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (image != null) {
g2d.drawImage(image, 0, 0, this);
}
if (drawCursor != null && cursorPoint != null) {
int x = (cursorPoint.x - (drawCursor.getBounds().width) / 2);
int y = (cursorPoint.y - (drawCursor.getBounds().height) / 2);
g2d.translate(x, y);
g2d.draw(drawCursor);
g2d.translate(-x, -y);
}
g2d.dispose();
}
public void updateDrawCursor(Point point, DrawOperation op) {
cursorPoint = point;
if (op != null) {
switch (op) {
case Draw:
drawCursor = new Ellipse2D.Float(0, 0, 4, 4);
break;
case Erase:
drawCursor = new Ellipse2D.Float(0, 0, eraseSize, eraseSize);
break;
}
} else {
drawCursor = null;
}
repaint();
}
protected void removeDrawCursor() {
drawCursor = null;
repaint();
}
protected void applyOperation(Point fromPoint, Point toPoint, DrawOperation op) {
if (image != null) {
if (op != null) {
Graphics2D g2d = image.createGraphics();
switch (op) {
case Draw:
g2d.setColor(Color.BLACK);
g2d.draw(new Line2D.Float(fromPoint, toPoint));
break;
case Erase:
g2d.setColor(Color.WHITE);
g2d.setStroke(new BasicStroke(eraseSize));
g2d.draw(new Line2D.Float(fromPoint, toPoint));
break;
}
g2d.dispose();
}
}
repaint();
}
}
}

Categories