the code:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PaintWindow {
private JFrame frame;
private aJPanel panel;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
PaintWindow window = new PaintWindow();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public PaintWindow() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new aJPanel();
frame.getContentPane().add(panel, BorderLayout.CENTER);
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
panel.stam();
}
});
frame.getContentPane().add(btnNewButton, BorderLayout.NORTH);
frame.setBounds(100, 100, 450, 300);
frame.setVisible(true);
}
public class aJPanel extends JPanel {
private static final long serialVersionUID = 8874943072526915834L;
private Graphics g;
public aJPanel() {
super();
System.out.println("Constructor");
}
public void paint(Graphics g) {
super.paint(g);
System.out.println("paint");
g.fillRect(10, 10, 10, 10);
this.g = g;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("paintComponent");
g.fillRect(20, 20, 20, 20);
this.g = g;
}
public void stam() {
System.out.println("stam");
this.g.fillRect(40, 40, 40, 40);
this.repaint();
}
}
}
what I want to do is paint custom shapes (lines, rectangles etc) after the user clicks a button or triggers a mouse event. but calling aJPanel.stam() does not show the rectangle its supposed to. I am fairly new to JPanel. any suggestions?
First of all:
class names should start with a capital letter
class names should be descriptive.
"aJPanel" does not follow either of the above.
but calling aJPanel.stam() does not show the rectangle its supposed to
See Custom Painting Apporoaches for the two common ways to do dynamic painting:
Add objects to a List and iterate the List to paint all the objects
Paint directly to a BufferedImage and then paint the BufferedImage
The examples add the Rectangle by dragging the mouse, but you can easily add Rectangles by just invoking the addRectangle(...) method when you click a button.
Related
Hello I am new to Java GUI I made a second.java which is as below:
package theproject;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class second extends JPanel implements ActionListener {
private Timer animator;
private ImageIcon imageArray[];
private int delay=50, totalFrames=8, currentFreames=1;
public second()
{
imageArray= new ImageIcon[totalFrames];
System.out.println(imageArray.length);
for(int i=0; i<imageArray.length;i++)
{
imageArray[i]=new ImageIcon(i+1+".png");
System.out.println(i+1);
}
animator= new Timer(delay, this);
animator.start();
}
public void paintComponent(Graphics g )
{
super.paintComponent(g);
if(currentFreames<8)
{
imageArray[currentFreames].paintIcon(this, g, 0, 0);
currentFreames++;
System.out.println(currentFreames);
}
else{
currentFreames=0;
}
}
#Override
public void actionPerformed(ActionEvent arg0) {
repaint();
}
}
And a Gui calling the constructor second and output is not showing . Can you please guide me what should I do and the gui is given below:
package theproject;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.SwingConstants;
import javax.swing.JTextField;
public class Sav {
private JFrame frame;
private JTextField textField;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Sav window = new Sav();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Sav() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
textField = new JTextField();
textField.setBounds(10, 0, 261, 20);
frame.getContentPane().add(textField);
textField.setColumns(10);
JButton btnNewButton = new JButton("Submit");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
second s= new second();
frame.add(s);
}
});
btnNewButton.setBounds(273, -1, 89, 23);
frame.getContentPane().add(btnNewButton);
}
}
The gui has to basically call the constructor and which will showcase the animation on the screen If someone what i am doing wrong or if something that has to be done please let me know .
First, don't update the state within the paintComponent method, paint can occur for a number of reasons at any time, mostly without your interaction. Painting should simple paint the current state. In your ActionListener, you should advance the frame and make decisions about what should occur (like resetting the frame value)
Second, you never actually add second to anything, so it will never be displayed.
Third, you don't override getPreferredSize in second, so the layout managers will have no idea what size the component should be and will simply be assigned 0x0, making it as good as invisible as makes no difference
Fourth, you're using null layouts. This is going to make you life impossibly hard. Swing has been designed and optimised around the use of layout managers, they do important work in deciding how best to deal with differences in font metrics across different rendering systems/pipelines, I highly recommend that you take the time to learn how to use them
Fifthly, paintComponent has no business been public, no one should ever call it directly
Example
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;
public class Sav {
private JFrame frame;
private JTextField textField;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Sav window = new Sav();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Sav() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
textField = new JTextField(20);
frame.getContentPane().add(textField, gbc);
JButton btnNewButton = new JButton("Submit");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
second s = new second();
frame.add(s, gbc);
frame.getContentPane().revalidate();
frame.pack();
frame.setLocationRelativeTo(null);
}
});
frame.getContentPane().add(btnNewButton, gbc);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public class second extends JPanel implements ActionListener {
private Timer animator;
private ImageIcon imageArray[];
private int delay = 50, totalFrames = 8, currentFreames = 1;
public second() {
imageArray = new ImageIcon[totalFrames];
for (int i = 0; i < imageArray.length; i++) {
imageArray[i] = new ImageIcon(getImage(i));
}
animator = new Timer(delay, this);
animator.start();
}
protected Image getImage(int index) {
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
FontMetrics fm = g2d.getFontMetrics();
g2d.dispose();
String text = Integer.toString(index);
int height = fm.getHeight();
int width = fm.stringWidth(text);
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
g2d = img.createGraphics();
g2d.setColor(getForeground());
g2d.drawString(text, 0, fm.getAscent());
g2d.dispose();
return img;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(imageArray[0].getIconWidth(), imageArray[1].getIconHeight());
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
imageArray[currentFreames].paintIcon(this, g, 0, 0);
}
#Override
public void actionPerformed(ActionEvent arg0) {
currentFreames++;
if (currentFreames >= imageArray.length) {
currentFreames = 0;
}
repaint();
}
}
}
Your code is also not working. It increment the values of image set but do not displays the images
Works just fine for me...
imageArray[i]=new ImageIcon(i+1+".png"); will not generate any errors if the image can't be loaded for some reason (and it will load the images in the background thread, which is just another issue).
Instead, I would recommend using ImageIO.read instead, which will throw a IOException if the image can't be read for some reason, which is infinitely more useful. See Reading/Loading an Image for more details
I am new in java and i wanted to work on a simple paint program using java swing.
my simple paint program should draw a shape like triangle, circle and square whenever i clicked on buttons.
i managed to draw these shapes and print it without buttons but i can not do it using ActionListener?
As you see i have a single button at the moment, i want to draw the oval whenever this button is clicked.
This is the code that i am working on it so far:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class PaintProject extends JComponent implements ActionListener{
public static void main(String[] args) {
JFrame frame=new JFrame("NEW PAINT PROGRAME!");
JButton button1=new JButton("ADD");
PaintProject paint=new PaintProject();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(paint);
frame.add(button1);
frame.pack();
frame.setVisible(true);
}
#Override
public Dimension getPreferredSize(){
return new Dimension(500,500);
}
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.red);
g.fillOval(0,0, 100, 100);
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
Could you please take following steps:
Step 1:
Insert button1.addActionListener(paint); just after PaintProject paint=new PaintProject(); in the main method of PaintProject.java
Step 2:
Remove the method named protected void paintComponent(Graphics g). Instead create following method:
private void drawOval(){
Graphics g = this.getGraphics();
g.setColor(Color.red);
g.fillOval(0,0, 100, 100);
}
Step 3:
Call the above method as follows:
#Override
public void actionPerformed(ActionEvent e) {
drawOval();
}
EDIT:
Following example demonstrates how to draw two shapes when respective buttons are clicked:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
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.WindowConstants;
public class PaintProject extends JComponent implements ActionListener {
public static void main(String[] args) {
JFrame frame = new JFrame("NEW PAINT PROGRAME!");
JButton ovalButton = new JButton("Oval");
ovalButton.setActionCommand("Oval");
JButton rectangleButton = new JButton("Rectangle");
rectangleButton.setActionCommand("Rectangle");
PaintProject paint = new PaintProject();
ovalButton.addActionListener(paint);
rectangleButton.addActionListener(paint);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(paint);
frame.add(ovalButton);
frame.add(rectangleButton);
frame.pack();
frame.setVisible(true);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
private void drawOval() {
Graphics g = this.getGraphics();
g.setColor(Color.red);
g.fillOval(0, 0, 100, 100);
}
private void drawRectangle() {
Graphics g = this.getGraphics();
g.setColor(Color.green);
g.fillRect(150, 150, 100, 100);
}
#Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (command.equals("Oval")) {
drawOval();
} else if (command.equals("Rectangle")) {
drawRectangle();
}
}
}
hi there i'm trying to improve myself about java2D and first of all i'm dealing with drawing polygons. However, i can not see the polygon on frame. I read some tutorials and examples but as i said i face with problems. here is the sample code of drawing a polygon;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Polygon;
import javax.swing.JFrame;
public class jRisk extends JFrame {
private JFrame mainMap;
private Polygon poly;
public jRisk(){
initComponents();
}
private void initComponents(){
mainMap = new JFrame();
mainMap.setSize(800, 600);
mainMap.setResizable(false);
mainMap.setVisible(true);
mainMap.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
int xPoly[] = {150,250,325,375,450,275,100};
int yPoly[] = {150,100,125,225,250,375,300};
poly = new Polygon(xPoly, yPoly, xPoly.length);
}
protected void paintComponent(Graphics g){
super.paintComponents(g);
g.setColor(Color.BLUE);
g.drawPolygon(poly);
}
/**
* #param args
*/
public static void main(String[] args) {
new jRisk();
}
}
JFrame does not have a paintComponent(Graphics g) method. Add the #Override annotation and you will get a compile time error.
1) Use JPanel and override paintComponent (you would than add JPanel to the JFrame viad JFrame#add(..))
2) Override getPreferredSize() to return correct Dimensions which fit your drawing on Graphics object or else they wont be seen as JPanel size without components is 0,0
3) dont call setSize on JFrame... rather use a correct LayoutManager and/or override getPrefferedSize() and call pack() on JFrame after adding all components but before setting it visible
4) Have a read on Concurrency in Swing specifically about Event Dispatch Thread
5) watch class naming scheme should begin with a capital letter and every first letter of a new word thereafter should be capitalized
6) Also you extend JFrame and have a variable JFrame? Take away the extend JFrame and keep the JFrame variable as we dont want 2 JFrames and its not good practice to extend JFrame unless adding functionality
Here is your code with above fixes (excuse picture quality but had to resize or it was going to 800x600):
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Polygon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class JRisk {
private JFrame mainMap;
private Polygon poly;
public JRisk() {
initComponents();
}
private void initComponents() {
mainMap = new JFrame();
mainMap.setResizable(false);
mainMap.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
int xPoly[] = {150, 250, 325, 375, 450, 275, 100};
int yPoly[] = {150, 100, 125, 225, 250, 375, 300};
poly = new Polygon(xPoly, yPoly, xPoly.length);
JPanel p = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.drawPolygon(poly);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
};
mainMap.add(p);
mainMap.pack();
mainMap.setVisible(true);
}
/**
* #param args
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new JRisk();
}
});
}
}
As per your comment:
i am preparing a map which includes lots of polygons and yesterday i
used a JPanel over a JFrame and i tried to check if mouse was inside
of the polygon with MouseListener. later i saw that mouseListener gave
false responds (like mouse is not inside of the polygon but it acts
like it was inside the polygon). so i deleted the JPanel and then it
worked
Here is updated code with MouseAdapter and overridden mouseClicked to check if click was within polygon.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class JRisk {
private JFrame mainMap;
private Polygon poly;
public JRisk() {
initComponents();
}
private void initComponents() {
mainMap = new JFrame();
mainMap.setResizable(false);
mainMap.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
int xPoly[] = {150, 250, 325, 375, 450, 275, 100};
int yPoly[] = {150, 100, 125, 225, 250, 375, 300};
poly = new Polygon(xPoly, yPoly, xPoly.length);
JPanel p = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.drawPolygon(poly);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
};
MouseAdapter ma = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent me) {
super.mouseClicked(me);
if (poly.contains(me.getPoint())) {
System.out.println("Clicked polygon");
}
}
};
p.addMouseListener(ma);//add listener to panel
mainMap.add(p);
mainMap.pack();
mainMap.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new JRisk();
}
});
}
}
JFrame does not extend JComponent so does not override paintComponent. You can check this by adding the #Override annotation.
To get this functionality extract paintComponent to a new class which extends JComponent. Don't forget to call super.paintComponent(g) rather than super.paintComponents(g).
Replace
protected void paintComponent(Graphics g){
super.paintComponents(g);
g.setColor(Color.BLUE);
g.drawPolygon(poly);
}
With
protected void paint(Graphics g){
super.paint(g);
g.setColor(Color.BLUE);
g.drawPolygon(poly);
}
Problem: I am trying to update the canvas with new painting objects based on user action. The canvas dosent get updated.
What i have done: The user interacts with the DnD action,The transferrable object reaches the canvas, Calls an update graphics method created by me. And the method simply uses the aldready created graphics 2d object and draws images using it.I have checkd the DnD action,the object is properly recived at canvas class and i was able to print them out using System.out.println.
A sample code,that has a similar function to that of mine,
Paint class:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class PaintPanel extends JPanel{
private Graphics2D drawImage;
public PaintPanel()
{
}
#Override
public void paint(Graphics g) {
drawImage = (Graphics2D) g;
drawImage.setColor(Color.WHITE);
drawImage.fillRect(0, 0, getWidth(), getHeight());
}
public void updateGraphics(int length,int width)
{
drawImage.setColor(Color.black);
drawImage.drawRect(100, 150, length, width);
repaint();
}
}
mainframe class:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class MainPaint extends JFrame{
public MainPaint()
{
setTitle("test paint");
setSize(400,400);
setLayout(new BorderLayout());
final PaintPanel paintPan = new PaintPanel();
JButton testButon = new JButton("Display shape");
add(paintPan,BorderLayout.CENTER);
add(testButon,BorderLayout.PAGE_END);
testButon.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
paintPan.updateGraphics(50,50);
repaint();
}
});
setVisible(true);
}
public static void main(String[] args)
{
new MainPaint();
}
}
Graphics2D drawImage; //source of the problem!
Don't attempt to cache a Graphics (or Graphics2D) instance! Instead:
Add the new objects to a list
Call repaint().
In paintComponent(Graphics) draw the list of objects.
An alternative to that is to use a BufferedImage as the drawing object. See this answer for an example.
Update - SSCCE based on latest code.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MainPaint extends JFrame {
public MainPaint() {
setTitle("test paint");
setSize(400, 400);
setLayout(new BorderLayout());
final PaintPanel paintPan = new PaintPanel();
JButton testButon = new JButton("Display shape");
add(paintPan, BorderLayout.CENTER);
add(testButon, BorderLayout.PAGE_END);
testButon.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
paintPan.updateGraphics(50, 50);
repaint();
}
});
setVisible(true);
}
public static void main(String[] args) {
new MainPaint();
}
}
class PaintPanel extends JPanel {
private int x, y;
private Color color = null;
public PaintPanel() {
setBackground(Color.ORANGE);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D drawImage = (Graphics2D) g;
if (color != null) {
drawImage.setColor(color);
drawImage.drawRect(100, 150, x, y);
}
}
public void updateGraphics(int length, int width) {
color = Color.RED;
x = length;
y = width;
repaint();
}
}
Note
There are still a number of things about that code that need changing. I decided to stop at the earliest variant that worked to display the rectangle on button click.
I think you need to call the validate() method.
I try to make a window with a resize handle at the bottom right.
So far I managed to detect the mouse hover and dragging.
The mouse cursor is changing to resize cursor successfully.
But the actually resize operation I'm unsure how to solve.
The Idea I testet at first place is to just setsize on parent when dragging on resize handle.
It works, but then the window get's resize immediately, that's not how the standard resize looks.
The standard resize is a transparent window with white border (may be different on different systems and look and feel).
Is it possible to trigger/use the built in resize mechanism?
Below you have a sample code.
Thanks!
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class main extends JFrame {
private JPanel contentPane;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
main frame = new main();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public class StatusBar extends JPanel implements MouseListener, MouseMotionListener {
private Polygon resizeCorner = new Polygon();
private int offsetX;
private int offsetY;
private Dimension offsetSize;
private Cursor resizeCursor = new Cursor(Cursor.SE_RESIZE_CURSOR);
private Cursor defaultCursor = new Cursor(Cursor.DEFAULT_CURSOR);
public StatusBar() {
super();
setPreferredSize(new Dimension(200,40));
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
private void createResizeHandle() {
resizeCorner.reset();
resizeCorner.addPoint(getWidth()-2, getHeight()-2);
resizeCorner.addPoint(getWidth()-40, getHeight()-2);
resizeCorner.addPoint(getWidth()-2, getHeight()-40);
}
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2;
g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g2.setColor(Color.red);
createResizeHandle();
g2.drawPolygon(resizeCorner);
}
#Override
public void mouseDragged(MouseEvent e) {
if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) {
int width = (int) (this.offsetSize.getWidth() - this.offsetX + e.getXOnScreen());
int height = (int) (this.offsetSize.getHeight() - this.offsetY + e.getYOnScreen());
this.getRootPane().getParent().setSize(width, height);
createResizeHandle();
}
}
#Override
public void mouseMoved(MouseEvent e) {
if (resizeCorner.contains(e.getX(), e.getY())) {
setCursor(resizeCursor);
} else {
setCursor(defaultCursor);
}
}
#Override
public void mouseClicked(MouseEvent arg0) {
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent e) {
if (resizeCorner.contains(e.getX(), e.getY())) {
this.offsetX = e.getXOnScreen();
this.offsetY = e.getYOnScreen();
this.offsetSize = this.getRootPane().getParent().getSize();
}
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
}
public main() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
JLabel lblNewLabel = new JLabel("New label");
StatusBar bar = new StatusBar();
contentPane.add(lblNewLabel, BorderLayout.NORTH);
contentPane.add(bar, BorderLayout.SOUTH);
}
}
lots of small mistakes, starts with correct naming for ClassName ... end with usage java reserved words for class/void/method's name(s)
minor changes (now it works for me), with one my mistake against Swing rules, I set there setPreferredSize(new Dimension(400, 300));, lets childrens returns PreferredSize for Container
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class MyToolBar extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
public class StatusBarX extends JPanel implements MouseListener, MouseMotionListener {
private static final long serialVersionUID = 1L;
private Polygon resizeCorner = new Polygon();
private int offsetX;
private int offsetY;
private Dimension offsetSize;
private Cursor resizeCursor = new Cursor(Cursor.SE_RESIZE_CURSOR);
private Cursor defaultCursor = new Cursor(Cursor.DEFAULT_CURSOR);
public StatusBarX() {
super();
setPreferredSize(new Dimension(200, 40));
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
private void createResizeHandle() {
resizeCorner.reset();
resizeCorner.addPoint(getWidth() - 2, getHeight() - 2);
resizeCorner.addPoint(getWidth() - 40, getHeight() - 2);
resizeCorner.addPoint(getWidth() - 2, getHeight() - 40);
}
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2;
g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2.setColor(Color.red);
createResizeHandle();
g2.drawPolygon(resizeCorner);
}
#Override
public void mouseDragged(MouseEvent e) {
if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) {
int width = (int) (this.offsetSize.getWidth() - this.offsetX + e.getXOnScreen());
int height = (int) (this.offsetSize.getHeight() - this.offsetY + e.getYOnScreen());
this.getRootPane().getParent().setSize(width, height);
createResizeHandle();
}
}
#Override
public void mouseMoved(MouseEvent e) {
if (resizeCorner.contains(e.getX(), e.getY())) {
setCursor(resizeCursor);
} else {
setCursor(defaultCursor);
}
}
#Override
public void mouseClicked(MouseEvent arg0) {
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent e) {
if (resizeCorner.contains(e.getX(), e.getY())) {
this.offsetX = e.getXOnScreen();
this.offsetY = e.getYOnScreen();
this.offsetSize = this.getRootPane().getParent().getSize();
}
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
}
public MyToolBar() {
JLabel lblNewLabel = new JLabel("New label");
StatusBarX bar = new StatusBarX();
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
contentPane.add(lblNewLabel, BorderLayout.NORTH);
contentPane.add(bar, BorderLayout.SOUTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocation(100, 100);
setPreferredSize(new Dimension(400, 300));
add(contentPane);
pack();
setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
MyToolBar frame = new MyToolBar();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
The standard resize is a transparent window with white border (may be different on different systems and look and feel).
When using Windows XP the standard is to resize top level components (frame, dialog etc) immediately. It doesn't matter what the LAF is.
In general other components don't have resizing functionality built in. The only exception to this that I can think of is JInternalFrame. In this case is does support the "outline" resizing of a component.
So if you want to add this type of functionality to your component then you would need to look at the internal frame UI to find the resizing code.
I would guess that the code would display a Glass Pane when dragging starts and then do the outline custom painting on the Glass Plane. Then on mouseReleased the frame size would be changed.
In case you are interested, Component Resizing shows how I do resizing for any component. It does immediate resizing, not outline resizing.