how can i draw a line on BufferedImage? - java

I am trying to create some kind of Paint program. I created a BufferedImage and an Graphics2D but i cant draw on it. All what I can see is the BufferedImage itself without any changes.
public class paintapp implements ActionListener, MouseListener, MouseMotionListener
{
public static final int WIDTHBUFF=300;
public static final int HEIGHTBUFF=300;
BufferedImage buffimage=new BufferedImage(WIDTHBUFF,HEIGHTBUFF,BufferedImage.TYPE_INT_BGR);
JLabel imagelabel=new JLabel(new ImageIcon(buffimage));
int s=3;
Color curr_color=Color.BLACK;
int x,y;
public static final int WIDTH=700;
public static final int HEIGHT=700;
public paintapp()
{
Graphics2D g2d=buffimage.createGraphics();
g2d.setBackground(Color.WHITE);
g2d.fillRect(0, 0, WIDTHBUFF,HEIGHTBUFF);
JFrame frame=new JFrame("Painter");
frame.setSize(WIDTH, HEIGHT);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.setVisible(true);
Panel buttonpanel=new Panel();
Panel colors=new Panel();
Panel draw=new Panel();
draw.add(imagelabel);
frame.add(draw);
frame.pack();
}
public static void main(String[]args)
{
paintapp paint1=new paintapp();
}
#Override
public void mouseDragged(MouseEvent e) {
Graphics2D g2=buffimage.createGraphics();
g2.setColor(curr_color);
g2.setStroke(new BasicStroke(s));
g2.drawLine(x, y, e.getX(), e.getY());
x=e.getX();
y=e.getY();
}
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent e) {
x=e.getX();
y=e.getY();
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}

I see you are poking through and you got things in jumbled up order. If you read the guides you will see how things go.
The first main thing is to add a MouseMotionListener to the drawing thing - be that JLabel JPanel whatever.
The second thing is that once you go outside of the constructor the JFrame is lost (unless you do some fancy things) and cant be accessed to be refreshed, so the system decides when to refresh and you will see - after you add the mouse listener - that your drawing will appear once you hide and show again the drawing window.
So you need to have JFrame as global - why dont you have you class extend JFrame and so no need to have some extra JFrame.

Related

Add functionality to Graphics

This is my code, I want to add functionality to the Rect that I made, like when you click on it, a window pops up
public class codetwo extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.LIGHT_GRAY);
g.setColor(Color.RED);
g.fillRect(110,110, 120, 120);
}
public static void main(String args[]) {
codetwo cd = new codetwo();
JFrame frame = new JFrame("Title");
frame.add(cd);
frame.setSize(440,350);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
You need to use Mouselistener for this.
public class codetwo extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.LIGHT_GRAY);
g.setColor(Color.RED);
g.fillRect(110,110, 120, 120);
}
public static void main(String args[]) {
codetwo cd = new codetwo();
cd.addMouseListener(new MouseListener(){
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
if (e.getX() >= 110 && e.getX() <= 230 && e.getY() >= 110 && e.getY() <= 230) {
JOptionPane.showMessageDialog(cd, "Some one clicked here ?", "Listening", JOptionPane.INFORMATION_MESSAGE);
}
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
JFrame frame = new JFrame("Title");
frame.add(cd);
frame.setSize(440,350);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

Java - Drawing shape with mouse and drag after clicking button

I would like to do this without the use of the JComponent. The idea is to have multiple buttons for each a shape, by clicking a button, I can then draw the shape for that button. Unfortunately, I can't even draw the shapes right now.
public static void main(String[] args) {
JFrame frame = new JFrame();
JButton rect = new JButton("Rectangle");
ActionListener rListener = new RectangleNode();
rect.addActionListener(rListener);
MouseListener rMListener = new RectangleNode();
rect.addMouseListener(rMListener);
MouseMotionListener rMMListener = new RectangleNode();
rect.addMouseMotionListener(rMMListener);
JButton ellipse = new JButton("Ellipse");
JPanel panel = new JPanel();
panel.add(rect);
panel.add(ellipse);
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.setTitle("Graph Draw");
frame.setVisible(true);
}
The RectangleNode class
public class RectangleNode implements ActionListener,MouseListener,MouseMotionListener {
private Point p1;
private Rectangle r;
private boolean rdraw;
#Override
public void actionPerformed(ActionEvent e) {
rdraw = true;
}
#Override
public void mousePressed(MouseEvent e) {
if(rdraw = true){
p1 = e.getPoint();
r = new Rectangle(p1.x, p1.y, p1.x - p1.x, p1.y - p1.y);
}
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseDragged(MouseEvent e) {
if(rdraw = true){
int x = Math.min(p1.x, e.getX());
int y = Math.min(p1.y, e.getY());
int width = Math.abs(p1.x - e.getX());
int height = Math.abs(p1.y - e.getY());
r.setBounds(x, y, width, height);
repaint();
}
}
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.draw(r); ;
}
}
I'm not sure how to use repaint, and the paintComponent method in this situation.
Check out Custom Painting Approaches for an example of how to dynamically draw Rectangles.
In your case you want the ability to draw a Rectangle or an Ellipse so you would need to make some changes:
The Java API supports a Shape class. A Shape can be a Rectangle, Ellipse, Polygon etc. So you would need to change the "ColoredRectangle" class to a "ColoredShape" class. This would allow you to store a Rectangle or an Ellipse.
Then in the paintComponent() code you would need to change the drawRect(..) method to be a draw( Shape ) so you can draw both Rectangles and Ellipses.
In the mouseDragged() logic you would need to modify the logic to check if you want to draw a Rectangle or an Ellispse. Then you would create the proper Shape and again use the draw( Shape ) method instead of the drawRect(...) method.
Then you would need to add a property to the class to control which Shape you want to paint. Then when you click the button you set the property. Or maybe instead of using a button you set up radio buttons for each Shape.
Anyway, play with the original code to understand how it works. That is start by converting the code to use the ColoredShape class just for Rectangles. Then once that works you can add the support for the Ellipse.

Costume component error "no ComponentUI class"

I am creating a costume component in Model UIDelegate using DrawPad example. However, for some reason I get the error UIDefaults.getUI() failed: no ComponentUI class. I am not even sure if I am implementing Model UIDelegate properly. But why am I getting that error?
Main
public class Main {
static JFrame frame;
static JButton clearButton;
static DrawPad drawPad;
public static void main(String[] args) {
UIManager.put("DrawPadUI", "BasicDrawPadUI");
frame = new JFrame();
drawPad = new DrawPad();
clearButton = new JButton("Clear");
frame.add(drawPad, BorderLayout.CENTER);
clearButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
Graphics g = frame.getGraphics();
g.setColor(Color.white);
g.fillRect(0, 0, frame.getWidth(), frame.getHeight());
}
});
frame.add(clearButton, BorderLayout.SOUTH);
frame.setSize(280, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
BasicDrawPadUI
public class BasicDrawPadUI extends ComponentUI implements MouseListener, MouseMotionListener {
Image image;
Graphics2D graphics2D;
int currentX, currentY, oldX, oldY;
JFrame frame;
JButton clearButton;
public static ComponentUI createUI(JComponent c) {
return new BasicDrawPadUI();
}
public void paintComponent(Graphics g, JComponent c) {
if (image == null) {
image = c.createImage(c.getWidth(), c.getHeight());
graphics2D = (Graphics2D) image.getGraphics();
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
clear(c);
}
g.drawImage(image, 0, 0, null);
}
#Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
currentX = e.getX();
currentY = e.getY();
if (graphics2D != null)
graphics2D.drawLine(oldX, oldY, currentX, currentY);
//repaint();
oldX = currentX;
oldY = currentY;
}
public void clear(JComponent c) {
graphics2D.setPaint(Color.white);
graphics2D.fillRect(0, 0, c.getWidth(), c.getHeight());
graphics2D.setPaint(Color.black);
c.repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
oldX = e.getX();
oldY = e.getY();
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
DrawPad
class DrawPad extends JComponent {
private final static String ID = "DrawPadUI";
public DrawPad() {
updateUI();
}
public void updateUI() {
setUI(UIManager.getUI(this));
}
#Override
public String getUIClassID() {
return ID;
}
}
Change UIManager.put("DrawPadUI", "BasicDrawPadUI"); to UIManager.put("DrawPadUI", "drawpad.BasicDrawPadUI");
You need to specify the full qualified class name of the UI class, including the package name
I'll need to have a look to be sure, but when it calls createUI, you could grab a reference to the component
Override the installUI method from ComponentUI and when it's called, maintain a reference to the component that is passed to you.
private DrawPad drawPad;
//...
#Override
public void installUI(JComponent c) {
drawPad = (DrawPad) c;
// Install required listeners and other functionality
}
Equally, in uninstallUI, you should dereference any strong references you have and uninstall your listeners
#Override
public void uninstallUI(JComponent c) {
// Uninstall any listeners
drawPad = null;
}
Have a look at custom java Swing component Model, UIDelegate, component format for a complete implementation.
Also, you should NEVER maintain a reference to a Graphics2D context that you did not create yourself

Java - JFrame keeps freezing after I type some Letters into a JTextField

I have no Idea why my JFrame keeps freezeing after I type Letters into the JTextField "Username" and "Password" :/ Could anyone look thru my code and tell my why and fix it please ?
public class Main
{
public static void main(String [ ] args)
{
LoginWindow loginframe = new LoginWindow();
loginframe.setVisible(true);
loginframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
loginframe.initialize();
while(true)
{
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
loginframe.Repaint();
}
}
}
FrameClass:
public class LoginWindow extends JFrame implements MouseListener, KeyListener, MouseMotionListener{
public LoginWindow(){
setSize(806, 629);
setResizable(false);
setLayout(new BorderLayout());
background = new JLabel(ResourceLoader.Iconload("/main_01.jpg"));
background.setBounds(0, 0, 800, 600);
add(background);
background.setLayout(null);
Username = new JTextField("", 20);
Username.setForeground(Color.WHITE);
Username.setBounds(312, 433, 170, 40);
Username.setFont(new Font("Impact", Font.BOLD, 25));
Username.setBackground(Color.BLACK);
Username.setBorder(BorderFactory.createMatteBorder(0, 0, 5, 0, Color.BLACK));
background.add(Username);
Password = new JPasswordField("", 20);
Password.setForeground(Color.WHITE);
Password.setBounds(312, 489, 170, 40);
Password.setBackground(Color.BLACK);
Password.setBorder(BorderFactory.createMatteBorder(0, 0, 5, 0, Color.BLACK));
Password.setFont(new Font("Serif", Font.BOLD, 25));
background.add(Password);
}
public void initialize()
{
makestrat();
addKeyListener(this);
requestFocus();
addMouseListener(this);
addMouseMotionListener(this);
}
public void makestrat()
{
createBufferStrategy(2);
strat = getBufferStrategy();
}
public void Repaint()
{
//System.out.println(mouseX + " " + mouseY);
Graphics g = strat.getDrawGraphics();
paintComponents(g);
Draw(g);
g.dispose();
strat.show();
}
public void Update()
{
}
public void Draw(Graphics g)
{
if(((mouseX >= 499) && (mouseX <= 669)) && ((mouseY >= 433)&&( mouseY <= 530))){
g.drawImage(ResourceLoader.ImageLoad("/login_02.jpg"), 502, 459, null);
}else{
g.drawImage(ResourceLoader.ImageLoad("/login_01.jpg"), 502, 459, null);
}
}
private class thehandler implements ActionListener{
#Override
public void actionPerformed(ActionEvent event) {
}
}
public void mouseMoved(MouseEvent event)
{
mouseY = event.getY()-26;
mouseX = event.getX()-3;
}
#Override
public void mouseClicked(MouseEvent e) {
PointerInfo a = MouseInfo.getPointerInfo();
Point point = new Point(a.getLocation());
SwingUtilities.convertPointFromScreen(point, e.getComponent());
double mouseX = (int) point.getX();
double mouseY = (int) point.getY();
System.out.println("(ContainerPos) Mouse clicked! X: " + mouseX + " Y: " + mouseY);
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void keyPressed(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseDragged(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
You don't need the while loop with the Thread.sleeap(). It's screwing with your program.
What you're trying to achieve here, a call to repaint continuously, can easily be accomplished with a javax.swing.Timer
Don't explicitly call paintComponent. An actual call to the real repaint() method will do that for you. No need to create an imitation Repaint()
Use a JPanel for painting instead of trying to paint on a JFrame
I would initialize, then set visible
Your code doesn't even compilable, so I can try and make fixes for you.
Use Java naming convention: methods and variable start with lower case letters.
Here's an example of a simple Login Window, using a modal JDialog
Learn how to use Layout Managers instead of relying on setBounds()
Point 2. Your main should look like this
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run(){
LoginWindow loginframe = new LoginWindow();
loginframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
loginframe.initialize();
loginframe.setVisible(true);
}
});
}
And in your constructor, have a javax.swing.Timer instead of your while loop
private Timer timer = null;
private DrawPanel drawPanel = new DrawPanel(); // see below for DrawPanel
public LoginWindow() {
// add drawPanel somewhere
...
timer = new Timer (50, new ActionListener(){
public void actionPerformed(ActionEvent e) {
drawPanel.repaint();
}
});
timer.start();
}
Point 4. Have an inner JPanel class that you do all your painting in, and add that component to the frame. You'll need to override the paintComponent method.
private DrawPanel extends JPanel {
#Override
protected void paintComponent(Graophics g) {
super.paintComponent(g);
Draw(g);
}
}
The obvious thing is that you shouldn't use Swing (or AWT really) off of the AWT Event Dispatch Thread (EDT). Fix with java.awt.EventQueue.invokeLater and java.swing.Timer (not java.util!). Diagnose with jstack(and jps) or the relevant key sequence in the terminal window (um, ctrl-break in Windows, ctrl-3 in Linux).

How to rearrange layed out JPanels in a JPanel via drag

I have a very simple example. I'm trying to get working before i try and apply this to the more complex program I have planned. But I'm trying to be able to drag and drop the JPanels that are in say a Flow or Vertical Layout.
I'm not really sure where to start, as this isn't really anything I've dealt with before. But from what I've researched, it would seem that I surely need a listener on each JPanel, that listens for clicks. From here it will gather initial data from a mousePressed, and run a overridden repaint(), that will update the coordinates of the panel in the container. Then according to where the coordinate is placed, it will repack() and hopefully resize the panels.
Am I onto the right track?
import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.Border;
public class DraggablePanels extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
Border raisedbevel = BorderFactory.createRaisedBevelBorder();
int px, py;
JPanel main = new JPanel();
public DraggablePanels(){
this.setLayout(new FlowLayout());
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setResizable(false);
JPanel p1 = new JPanel();
p1.addMouseListener(new MouseListener(){
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
px = e.getX();
py = e.getY();
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
});
p1.setBorder(raisedbevel);
JPanel p2 = new JPanel();
p2.addMouseListener(new MouseListener(){
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
px = e.getX();
py = e.getY();
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
});
p2.setBorder(raisedbevel);
p1.add(new JLabel("Thing 1"));
p2.add(new JLabel("Thing 2"));
main.add(p1);
main.add(p2);
add(main);
pack();
setVisible(true);
}
public static void main (String args[]){
DraggablePanels d = new DraggablePanels();
}
}
Check this Sample Application for rearranging jpanel:
http://www.bryanesmith.com/docs/drag-and-drop-java-5/

Categories