Animation on Transparent-background JFrame Linux - java

I want to create a fully transparent background for a Frame (or JFrame) and have it show a transparent animation. I managed to get it working in Windows 7 x64 but the same code does not run on my Linux (Lubuntu x64 15.04).
The code below shows what I'm trying to achieve--just copy & paste it. I just want the little rectangle to move across the screen without leaving a trail.
static int a = 0;
public static void main(String[] args) {
JFrame f = new JFrame();
f.setUndecorated(true);
f.setBackground(new Color(0, 0, 0, 0));
f.setVisible(true);
f.setSize(512, 512);
f.add(new JPanel() {
#Override
public void paintComponent(Graphics gr) {
Graphics2D g = (Graphics2D)gr;
g.setBackground(new Color(0, 0, 0, 0));
g.clearRect(0, 0, 512, 512);
g.drawRect(a, a++, 2, 2);
}
});
while(true) {
try {
Thread.sleep(30);
} catch(InterruptedException e) {
e.printStackTrace();
}
f.repaint();
}
}
What I want to achieve (as shown in Windows) and what I get with Lubuntu 15.04:
I just want to see the little square move just like what's shown on Windows 7--I don't want to see a trail.
Please don't give me the link of Oracle's transparency and window documentation--I've gone over it all thrice.
What I've tried:
Graphics2D's 'copyArea()' of a transparent space. (This used to work AFAIK but no longer does)
GlassPane
AlphaComposite
setPaint()
Please please just test out your thoughts/code first. A lot of the "this should work" stuff I have already tried and does not seem to... All help is greatly appreciated.

For reference, here's a minimal complete example, suitable for cross-platform testing. Note that
On some platforms, e.g. Ubuntu, a completely transparent background is not seen as opaque; a small, non-zero alpha value is a typical work-around.
Swing GUI objects should be constructed and manipulated only on the event dispatch thread.
Use java.swing.Timer, which runs on the event dispatch thread, to pace the animation.
Don't use setPreferredSize() when you really mean to override getPreferredSize().
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
/**
* #see https://stackoverflow.com/a/31328464/230513
*/
public class TransparentAnimation {
private static final Color tranparentBlack = new Color(0, 0, 0, 1);
private void display() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setUndecorated(true);
f.setBackground(tranparentBlack);
f.add(new JPanel() {
int x, y;
Timer t = new Timer(10, (ActionEvent e) -> {
x = (x + 1) % getWidth();
y = (y + 1) % getHeight();
repaint();
});
{
setBackground(tranparentBlack);
t.start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
g.fillOval(x, y, 16, 16);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
});
f.add(new JLabel(System.getProperty("os.name") + "; v"
+ System.getProperty("os.version")), BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new TransparentAnimation()::display);
}
}

Basically this issue is OS-related. What works for Windows will not work for Linux and vice versa.
For some reason, Linux only allows animated per-pixel-transparency when setting up a BufferStrategy. However, this solution fails on Windows. As a result I have come up with the following code which picks the correct algorithm based on the OS:
static int a = 0;
public static void main(String[] args) {
JFrame f = new JFrame();
JPanel p = new JPanel() {
#Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setBackground(new Color(255, 255, 255, 0));
g2d.clearRect(0, 0, f.getWidth(), f.getHeight());
g2d.drawRect(a, a++, 2, 2);
}
};
f.add(p);
f.setUndecorated(true);
f.setBackground(new Color(255, 255, 255, 0));
f.setSize(512, 512);
f.setVisible(true);
f.createBufferStrategy(2);
BufferStrategy bs = f.getBufferStrategy();
while (true) {
try {
Thread.sleep(33);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (System.getProperty("os.name").contains("indows ")) {
p.repaint();
} else {
Graphics g = null;
do {
try {
g = bs.getDrawGraphics();
p.update(g);
} finally {
g.dispose();
}
bs.show();
} while (bs.contentsLost());
Toolkit.getDefaultToolkit().sync();
}
}
}
This code works for my Windows 7 x64 and my Lubuntu 15.04 x64. Please try out this code out yourself and see if it works for you. I myself don't own a Mac so if someone would please test it for me I would be very grateful. If it does not work for anyone, please let me know.
This is what you're supposed to see:

If we extend JFrame, set undecorated to true, and override paint with, we can make a transparent JFrame.
try this,
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestTransparentFrame {
private class PaintPanel extends JPanel {
private List<Point> points = new ArrayList<Point>();
public PaintPanel() {
setOpaque(false);
MouseAdapter adapter = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
points.clear();
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
points.add(e.getPoint());
repaint();
}
};
addMouseListener(adapter);
addMouseMotionListener(adapter);
setBorder(BorderFactory.createLineBorder(Color.GREEN));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (points.size() > 1) {
g.setColor(Color.RED);
Point p1 = points.get(0);
for (int i = 1; i < points.size(); i++) {
Point p2 = points.get(i);
g.drawLine(p1.x, p1.y, p2.x, p2.y);
p1 = p2;
}
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(700, 500);
}
}
protected void createAndShowGUI() throws MalformedURLException, IOException {
JFrame frame = new JFrame("Test transparent painting");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 50));
frame.add(new PaintPanel());
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
new TestTransparentFrame().createAndShowGUI();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}

Related

TextArea with Canvas Binding to Rect

I have the problem of this textarea not showing up when I run it. Is there any way to make it show up. BTW its getting called through the gameloop on a class that extends canvas.
public void render(Graphics g){
Graphics2D g2d = (Graphics2D) g;
if(!initialized)
init();
try {
test.requestFocus();
test.paintAll(g);
test.setText("hi");
test.setBounds(getBounds());
test.printAll(g);
} catch (Exception e) {
e.printStackTrace();
}
g2d.draw(getBounds());
g.drawRect(0, 0, 100, 100);
}
private void init(){
frame.setVisible(false);
initialized = true;
test = new TextArea();
test.setEditable(true);
test.setBounds(getBounds());
test.setBackground(test.getBackground());
test.setForeground(test.getForeground());
frame.add(test);
frame.repaint();
frame.setVisible(true);
System.out.println(test.isVisible());
}
private Rectangle getBounds(){
return new Rectangle(100, 100, 100, 100);
}
I have tried using JTextArea but it takes up the full screen and won't bind to a rect. Thanks for help in advance!
You don't need to manually paint existing Components you add to your program. Here is a simple example how to display a TextArea over a frame/canvas you paint yourself: Check the comments for further details.
package main;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.TextArea;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.Timer;
public class Test extends JFrame {
private static Test frame;
private static double t;
private static int x;
private static int y;
private static TextArea test;
public static void main(String[] args) {
frame = new Test();
frame.setVisible(true);
// set layout to null so that you can freely position your components
// without them "filling up the whole screen"
frame.setLayout(null);
frame.setSize(500, 500);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
// game loop
new Timer(10, (e) -> {
t += 10.0 / 1000;
x = (int) (100 + 50 * Math.sin(t));
y = (int) (100 + 50 * Math.cos(t));
// calling repaint will cause Test.paint() to be called first,
// then Test's children will be painted (= the TextArea)
frame.repaint();
}).start();
// initialize the textarea only once
test = new TextArea();
test.setEditable(true);
test.setBounds(new Rectangle(100, 100, 100, 100));
test.setText("hi");
frame.add(test);
}
#Override
public void paint(Graphics g) {
// put only painting logic in your paint/render.
// don't set the bounds of components here,
// as this will trigger a repaint.
g.setColor(Color.black);
g.fillRect(0, 0, 400, 400);
g.setColor(Color.yellow);
g.fillOval(x, y, 20, 20);
}
}

Background not changing color

So I'm trying to change the background on a full screen game I'm making from a tutorial, I'm trying to change the background to green, but it stays black, what's wrong with the code?
Screen.java
package debels;
import java.awt.*;
import javax.swing.JFrame;
public class Screen {
private GraphicsDevice vc;
public Screen(){
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
vc = env.getDefaultScreenDevice();
}
public void setFullScreen(DisplayMode dm, JFrame window){
window.setUndecorated(true);
window.setResizable(false);
vc.setFullScreenWindow(window);
if (dm != null && vc.isDisplayChangeSupported()){
try{
vc.setDisplayMode(dm);
}catch (Exception e){}
}
}
public Window getFullScreen(){
return vc.getFullScreenWindow();
}
public void restoreScreen(){
Window w = vc.getFullScreenWindow();
if (w != null){
w.dispose();
}
vc.setFullScreenWindow(null);
}
}
Main.java
package debels;
import java.awt.*;
import javax.swing.*;
public class Main extends JFrame{
private static final long serialVersionUID = -7498470134154894036L;
public static void main(String[] args){
DisplayMode dm = new DisplayMode(800, 600, 16, DisplayMode.REFRESH_RATE_UNKNOWN);
Main m = new Main();
m.run(dm);
}
public void run(DisplayMode dm){
setBackground(Color.GREEN);
setForeground(Color.BLUE);
setFont(new Font("Arial", Font.PLAIN, 24));
Screen s = new Screen();
try{
s.setFullScreen(dm, this);
try{
Thread.sleep(5000);
}catch(Exception e){}
}finally{
s.restoreScreen();
}
}
public void paint(Graphics g){
g.drawString("Hello", 200, 200);
}
}
Your first problem is going to be your paint method...
public void paint(Graphics g){
g.drawString("Hello", 200, 200);
}
Part of the responsibility of the paint method is to paint...the background. But since you're not calling super.paint this can't happen.
You should avoid overriding paint on top level containers, like JFrame and instead use a custom component, like JPanel for example, and override their paintComponent method (not forgetting to call super.paintComponent).
Another area of potential issue is the use of Thread.sleep, this could be causing the Event Dispatching Thread to be halted, preventing from processing new paint requests. A better solution might be to use a javax.swing.Timer, which will pause in the background and provide notification (via a ActionListener) within the context of the EDT...
For example
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.DisplayMode;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestFullScreen {
public static void main(String[] args) {
new TestFullScreen();
}
public TestFullScreen() {
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());
final Screen s = new Screen();
DisplayMode dm = new DisplayMode(800, 600, 16, DisplayMode.REFRESH_RATE_UNKNOWN);
s.setFullScreen(dm, frame);
Timer timer = new Timer(5000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
s.restoreScreen();
}
});
timer.start();
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setBackground(Color.GREEN);
setForeground(Color.WHITE);
setFont(new Font("Arial", Font.PLAIN, 24));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int width = getWidth();
int height = getHeight();
FontMetrics fm = g2d.getFontMetrics();
String text = "It's not easy to be green";
int x = (width - fm.stringWidth(text)) / 2;
int y = ((height - fm.getHeight()) / 2) + fm.getAscent();
System.out.println(width + "x" + height);
System.out.println(x + "x" + y);
g2d.drawString(text, x, y);
g2d.dispose();
}
}
public class Screen {
private GraphicsDevice vc;
public Screen() {
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
vc = env.getDefaultScreenDevice();
}
public void setFullScreen(DisplayMode dm, JFrame window) {
window.setUndecorated(true);
window.setResizable(false);
vc.setFullScreenWindow(window);
if (dm != null && vc.isDisplayChangeSupported()) {
try {
vc.setDisplayMode(dm);
} catch (Exception e) {
}
}
}
public Window getFullScreen() {
return vc.getFullScreenWindow();
}
public void restoreScreen() {
Window w = vc.getFullScreenWindow();
if (w != null) {
w.dispose();
}
vc.setFullScreenWindow(null);
}
}
}
This is what I did to overcome the challenge. I removed the setBackground, setForeground, and setFont from the run method in the Main class and added them to the setFullScreen method in the Screen class:
window.getContentPane().setBackground(Color.PINK);
window.setForeground(Color.BLUE);
window.setFont(new Font ("Arial", Font.PLAIN, 24));
Thereafter, I added "super.paint(g);" as the first line of the paint method in the Main class
You just need to make 3 little changes and it will work. Follow these steps:
Step-1:Add getContentPane() to setBackgroud() which is present in the run() method
getContentPane().setBackground(Color.GREEN);
Step-2: Cut & paste below lines from run() method to paint() method.
getContentPane().setBackground(Color.GREEN);
setForeground(Color.BLUE);
setFont(new Font("Arial", Font.PLAIN, 24));
step-3: Add super.paint(g) in the starting of paint() method. the whole paint() method will look like this;
public void paint(Graphics g){
super.paint(g);
getContentPane().setBackground(Color.GREEN);
setForeground(Color.BLUE);
setFont(new Font("Arial", Font.PLAIN, 24));
g.drawString("Hello", 200, 200);
}
if it still doesn't work let me know in the comment! #YNWA

making a button - java

Ok, i know that this question has been asked before, but i just can't seem to get my application to work with the help from other peoples posts.
I am just trying to make a screen with a picture i made and then 3 buttons (just like a game menu). I have done the image and i am now trying to make the 3 buttons like this.
my code at the moment is this:
public class Test {
static int WIDTH = 700;
static int HEIGHT = 600;
public static void main(String[] args) {
JLabel label = new JLabel();
JFrame f = new JFrame();
JPanel panel = new JPanel();
JButton button = new JButton("hello again");
button.addActionListener ((ActionListener) new Action1());
label.setIcon(new ImageIcon("C:\\Users\\barney\\workspace\\game\\res\\background.jpg"));
f.add(panel);
f.add(label);
f.setVisible(true);
f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
f.setSize(WIDTH, HEIGHT);
f.setResizable(false);
f.setLocationRelativeTo(null);
f.setTitle("2d platformer v1.1");
f.setVisible(true);
}
}
So how would i add the buttons like in the picture
also could you tell me if i have set my code out wrong as i am new to java.
thanks.
I'm going to be smacked around for this...
label.setLayout(new GridBagLayout());
GridBagConstraints gbc = GridBagConstraints();
gbc.insets = new Insets(4, 0, 4, 0);
gbc.gridwidth = GridBagConstraints.REMAINDER;
label.add(button, gbc);
// add the other buttons
Updated
Personally, I'd create a custom JPanel, that would paint the background and then add buttons to it, using the GridBagLayout from above
Updated
The problem with this question is "it depends"
It depends on how you want to implement the actual buttons. Because you've left "blank" spaces, I assume you intend to render some buttons onto the image. I would personally, render a full image and then add some normal buttons onto, but it's your project not mine.
If you wanted to use something like JButton (or any other Component), you would need a custom layout manager to help you align the components with gaps you have left. Hence the reason I would simply do a nice background and use something like GridBagLayout instead...
I apologize, I may have gone slightly over board, but I was having fun.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RadialGradientPaint;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ButtonImage {
public static void main(String[] args) {
new ButtonImage();
}
public ButtonImage() {
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 MenuPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class MenuPane extends JPanel {
public static final Rectangle NEW_GAME_BOUNDS = new Rectangle(221, 157, 262, 85);
public static final Rectangle LOAD_GAME_BOUNDS = new Rectangle(221, 276, 262, 85);
public static final Rectangle EXIT_GAME_BOUNDS = new Rectangle(221, 396, 262, 85);
private BufferedImage img;
private Rectangle selectedBounds;
public MenuPane() {
try {
img = ImageIO.read(getClass().getResource("/vtr1a.jpg"));
} catch (IOException ex) {
ex.printStackTrace();
}
MouseAdapter mouseHandler = new MouseAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
if (getNewGameBounds().contains(e.getPoint())) {
System.out.println("in new");
selectedBounds = getNewGameBounds();
} else if (getLoadGameBounds().contains(e.getPoint())) {
System.out.println("in load");
selectedBounds = getLoadGameBounds();
} else if (getExitGameBounds().contains(e.getPoint())) {
System.out.println("in exit");
selectedBounds = getExitGameBounds();
} else {
selectedBounds = null;
}
repaint();
}
#Override
public void mouseClicked(MouseEvent e) {
if (getNewGameBounds().contains(e.getPoint())) {
System.out.println("New Game");
} else if (getLoadGameBounds().contains(e.getPoint())) {
System.out.println("Load Game");
} else if (getExitGameBounds().contains(e.getPoint())) {
System.out.println("Exit Game");
}
}
};
addMouseListener(mouseHandler);
addMouseMotionListener(mouseHandler);
}
#Override
public Dimension getPreferredSize() {
return img == null ? super.getPreferredSize() : new Dimension(img.getWidth(), img.getHeight());
}
protected Point getImageOffset() {
Point p = new Point();
if (img != null) {
p.x = (getWidth() - img.getWidth()) / 2;
p.y = (getHeight() - img.getHeight()) / 2;
}
return p;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
Graphics2D g2d = (Graphics2D) g.create();
Point p = getImageOffset();
g2d.drawImage(img, p.x, p.y, this);
drawText(g2d, "New Game", getNewGameBounds());
drawText(g2d, "Load Game", getLoadGameBounds());
drawText(g2d, "Exit Game", getExitGameBounds());
g2d.dispose();
}
}
protected void drawText(Graphics2D g2d, String text, Rectangle bounds) {
FontMetrics fm = g2d.getFontMetrics();
g2d.setColor(Color.GRAY);
if (selectedBounds != null) {
if (bounds.contains(selectedBounds)) {
RadialGradientPaint rpg = new RadialGradientPaint(
new Point(bounds.x + (bounds.width / 2), bounds.y + (bounds.height / 2)),
Math.min(bounds.width, bounds.height),
new float[]{0f, 1f},
new Color[]{new Color(252, 180, 42), new Color(97, 205, 181)}
);
g2d.setPaint(rpg);
RoundRectangle2D fill = new RoundRectangle2D.Float(bounds.x, bounds.y, bounds.width, bounds.height, 22, 22);
g2d.fill(fill);
g2d.setColor(Color.WHITE);
}
}
g2d.drawString(
text,
bounds.x + ((bounds.width - fm.stringWidth(text)) / 2),
bounds.y + ((bounds.height - fm.getHeight()) / 2) + fm.getAscent());
}
protected Rectangle getNewGameBounds() {
return getButtonBounds(NEW_GAME_BOUNDS);
}
protected Rectangle getLoadGameBounds() {
return getButtonBounds(LOAD_GAME_BOUNDS);
}
protected Rectangle getExitGameBounds() {
return getButtonBounds(EXIT_GAME_BOUNDS);
}
protected Rectangle getButtonBounds(Rectangle masterBounds) {
Rectangle bounds = new Rectangle(masterBounds);
Point p = getImageOffset();
bounds.translate(p.x, p.y);
return bounds;
}
}
}
You could, just as easily, use separate images for each button and instead of rendering the text/graphics, render a image at the required position.
Check out Custom Painting and 2D Graphics for some more info.
I guess you didn't add Button to JFrame
f.add(button)
As you want different buttons than Swing button, to make the things simpler, you can draw your buttons in a JPanel (using the paintComponent method and Java 2D). Each JPanel will be a button. Them, you will use some mouse events to detect clicks, etc. Another approach is do the same thing that you are doing with your background (several JLabels with images) and register mouse events in each label. You can also create your own Look And Feel for your buttons, but this is not so simple. Of course, you will need to change your layout manager to fit your buttons.

Getting Unexpected output with the swing code

I'm trying to built a simple app which has a translucent frame and it draws lines where the user wants.I have also added listeners to catch the mouse events and these are displayed accordingly .Everything is working fine but the problems are:
1)the window is not transparent
2)it is completely black and the lines are appearing white.
Can anyone
Here is the code:
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class MouseListen2 extends JFrame implements MouseListener {
String str = "Nothing";
int x[][] = new int[100][2];
int count = 0;
int flag = 1;
boolean draw = false;
MouseListen2() {
super("Line Draw App");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 300);
this.addMouseListener(this);
setBackground(new Color(0, 0, 0, 0));
JPanel jp = new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Paint gp = new GradientPaint(300, 700, new Color(20, 20, 210, 0), 100, 00, new Color(10, 20, 40, 255));
g2.setPaint(gp);
g2.fillRect(0, 0, getWidth(), getHeight());
}
};
setContentPane(jp);
setVisible(true);
//c.setOpaque(true);
}
public void paint(Graphics g) {
//Graphics g=this.getGraphics();
//super.paint(g);
Graphics2D g2 = (Graphics2D) g;
g2.clearRect(0, 0, getWidth(), getHeight());
g2.drawString(str, 50, 50);
//initially count=0 hence i<-1 so loop will not automatically run in the beginning
for (int i = 0; i < count - 1; i = i + 2) {
g2.drawLine(x[i][0], x[i][1], x[i + 1][0], x[i + 1][1]);
}
//repaint(); using this here creates an infinite loop as after mouse event paint is called and at the end
//this method is again called using the repaint() and so on the loop continues.
}
public static void main(String[] args) {
JFrame.setDefaultLookAndFeelDecorated(true);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MouseListen2();
}
});
}
#Override
public void mouseClicked(MouseEvent e) {
str = "clicked";
repaint();
}
#Override
public void mousePressed(MouseEvent e) {
str = "pressed";
repaint();
x[count][0] = e.getX();
x[count][1] = e.getY();
count++;
}
#Override
public void mouseReleased(MouseEvent e) {
str = "released";
draw = true;
x[count][0] = e.getX();
x[count][1] = e.getY();
count++;
//draw();
repaint();
}
#Override
public void mouseEntered(MouseEvent e) {
str = "entered";
repaint();
}
#Override
public void mouseExited(MouseEvent e) {
str = "exited";
repaint();
}
}
have to add MouseListener to the JPanel, because you added MouseListener to the JFrame (this.addMouseListener(this);)
this code line setContentPane(jp); put JPanel to the BorderLayout.CENTER possition to the JFrame, in this case (isn't there any another JComponent added to the JFrame) fills whole / all available space into JFrame
then for mouse event is accesible only JPanel, mouse can't access to the JFrame's RootPane or ContentPane
remove / comment public void paint(Graphics g) and rellated code block move to the paintComponent for the JPanel
See How to Create Translucent and Shaped Windows.

resizable angle

I have an angle in a frame (I draw it with two lines). I want to make it flexible to frame; I mean, when the user expands the frame angle also become expanded and vice versa. I tried a lot of examples but I could not solve it. Can someone help?
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class LineDraw extends Frame {
Line2D line1 = new Line2D.Double(200, 200, 100, 300);
Stroke drawingStroke1 = new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0,
new float[] { 9 }, 0);
Line2D line2 = new Line2D.Double(200, 200, 200, 300);
public void paint(Graphics g) {
Graphics2D graph = (Graphics2D) g;
graph.setPaint(Color.red);
graph.draw(line2);
graph.setStroke(drawingStroke1);
graph.setPaint(Color.green);
graph.draw(line1);
}
public static void main(String args[]) {
Frame frame = new LineDraw();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
frame.setSize(300, 250);
frame.setVisible(true);
}
}
Here it is done in Swing. Everything is done in the EDT, as is intended with Swing as it is not thread safe. It is double buffered. Why the JLabel/Icon combination? It's just the best way to do it, as far as I have discovered, and I'd struggle to give you a historical/technical explanation of why - that's just the way it seems to have been designed. The other approach is to get involved with BufferStrategy but that starts to get more complicated IMHO.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class LineDrawSwing extends JLabel implements Icon {
Line2D line1, line2;
public LineDrawSwing() { this.setIcon(this); }
Stroke drawingStroke1 = new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0,
new float[] { 9 }, 0);
public static void main(String args[]) {
JFrame frame = new JFrame();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
frame.add(new LineDrawSwing());
frame.validate();
frame.setSize(300, 250);
frame.setVisible(true);
}
#Override
public void paintIcon(Component c, Graphics g, int x, int y) {
Dimension size = getSize();
line1 = new Line2D.Double(size.width/2, size.height-10, 10, 10);
line2 = new Line2D.Double(size.width/2, size.height-10, size.width-10, 10);
Graphics2D graph = (Graphics2D) g;
graph.setPaint(Color.red);
graph.draw(line2);
graph.setStroke(drawingStroke1);
graph.setPaint(Color.green);
graph.draw(line1);
}
#Override
public int getIconHeight() {
return getSize().height;
}
#Override
public int getIconWidth() {
return getSize().width;
}
}
If sticking with AWT, I would use a ComponentListener to track the size changes for the Frame and reset the line coordinates accordingly.
You may get away with creating/updating the lines in the Frame.paint() context, but that's just not a very clean implementation, with a lot of implied logic and assumptions and, therefore, probably some issues.
So here's the ComponentListener approach. I had to make a few assumptions about where you wanted your lines to get drawn from/to, as you were not clear on this. (If you can be clearer on this, I can update the example.)
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class LineDraw extends Canvas implements ComponentListener {
Line2D line1, line2;
public LineDraw() {
this.addComponentListener(this);
}
// set up lines every size update
public void componentResized(ComponentEvent e) {
Dimension size = getSize();
line1 = new Line2D.Double(size.width/2, size.height-10, 10, 10);
line2 = new Line2D.Double(size.width/2, size.height-10, size.width-10, 10);
}
// required to satisfy ComponentListener interface
public void componentHidden(ComponentEvent e) { }
public void componentMoved(ComponentEvent e) { }
public void componentShown(ComponentEvent e) { }
// paint, main both as before
Stroke drawingStroke1 = new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0,
new float[] { 9 }, 0);
public void paint(Graphics g) {
Graphics2D graph = (Graphics2D) g;
graph.setPaint(Color.red);
graph.draw(line2);
graph.setStroke(drawingStroke1);
graph.setPaint(Color.green);
graph.draw(line1);
}
public static void main(String args[]) {
Frame frame = new Frame();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
frame.add(new LineDraw());
frame.validate();
frame.setSize(300, 250);
frame.setVisible(true);
}
}

Categories

Resources