Image appears on mouse click on the cursor location in JFrame - java

I am trying to make a GUI in Java. I have a JFrame and I create a JPanel in it. I add them manually when I click on "Design".
When a click with the mouse on the Panel then an icon should appear where I clicked. It should appear as many times as I click on the Panel. I try to use the answer given here but it does not work as the Panel there is not added manually:
Add image on mouse click? Java applet
I am using the same code and I try to adjust it to the event MouseClicked for the jPanel1 which I have added manually:
private Point drawPoint;
Graphics g;
private void jPanel1MouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
System.out.println("I can click.");
Toolkit toolkit = Toolkit.getDefaultToolkit();
Image image = toolkit.getImage("Icons/p.png");
drawPoint = new Point(evt.getPoint());
repaint();
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (drawPoint != null) {
g2d.drawImage(image, drawPoint.x, drawPoint.y, this);
}
g2d.dispose();
}
It says that it cannot find symbol for:super.paintComponent(g)
If I use the given code in the example in a newly created class, it works fine without the fact that I want the image to appear again and again instead of removing it each time and appearing only once.
Does anyone know how to fix it?
EDIT
import javax.swing.JFrame;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.imageio.ImageIO;
import javax.swing.*;
public class editorPTnets{
private JButton b1;
private JButton b2;
private JButton b3;
private JButton b4;
public editorPTnets(){
JFrame f = new JFrame("P/T nets");
f.setSize(800, 500);
f.setLayout(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setBackground(Color.gray);
f.add(new TestPane());
f.setLocationRelativeTo(null);
JPanel p = new JPanel();
p.setBounds(5, 50, 760, 400);
p.setBackground(Color.white);
f.add(p);
p.setVisible(true);
b1 = new JButton("");
b1.setBounds(5, 5, 40, 40);
b1.setVisible(true);
b1.setIcon(new
ImageIcon("C:\\Users\\Toshiba\\Desktop\\Java\\Icons\\new.png"));
f.add(b1);
b2 = new JButton("");
b2.setBounds(50, 5, 40, 40);
b2.setIcon(new
ImageIcon("C:\\Users\\Toshiba\\Desktop\\Java\\Icons\\open.png"));
b2.setVisible(true);
f.add(b2);
f.setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new editorPTnets();
System.out.println("Hello, world");
public class TestPane extends JPanel {
Image image;
private Point drawPoint;
public TestPane() {
Toolkit toolkit = Toolkit.getDefaultToolkit();
image =
toolkit.getImage("C:\\Users\\Toshiba\\Desktop\\Java\\Icons\\p.png");
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
drawPoint = new Point(e.getPoint());
repaint();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 500);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (drawPoint != null) {
g2d.drawImage(image, drawPoint.x, drawPoint.y, this);
}
g2d.dispose();
}
}
}
EDIT 2 FIXED
public mainFrame() {
JFrame f = new JFrame("Editor for graphs");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(800, 600);
f.getContentPane().setBackground(Color.blue);
f.setResizable(false);
f.setLayout(new BorderLayout());
f.add(new Panel1(), BorderLayout.SOUTH);
f.setLocationRelativeTo(null);
f.setVisible(true);
This helped me fix the problem.

Related

String is not showing up in JFrame

I'm programming a little game where i want to show up a StartScreen and after clicking on it the game will start. But the String's don't show up.
The code is:
int nRows = 115;
int nCols = 42;
int[][] grid;
Font smallFont;
public hitit() {
setPreferredSize(new Dimension(1150,420));
setBackground(Color.orange);
setFont(new Font("SansSerif", Font.BOLD, 48));
smallFont = getFont().deriveFont(Font.BOLD,18);
setFocusable(true);
}
void drawStartScreen(Graphics2D g) {
g.setColor(Color.red);
g.setFont(smallFont);
g.drawString("hit it",600,100);
g.drawString("(click to start)", 250, 240);
}
public void paintComponent(Graphics2D gg) {
super.paintComponent(gg);
Graphics2D g = (Graphics2D) gg;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
drawStartScreen(g);
}
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("hit it");
f.setResizable(true);
f.add(new hitit(), BorderLayout.CENTER);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
I tried to implement a run-method but that didn't changed the problem
So I copy-pasted the code into a new file and now it's actually working
I don't know why, but the position for the two strings was not problem.
package testetetetet;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class hitit extends JPanel {
int nRows = 115;
int nCols = 42;
Font smallFont;
public hitit() {
setPreferredSize(new Dimension(1150, 420));
setBackground(Color.orange);
setFont(new Font("SansSerif", Font.BOLD, 48));
setFocusable(true);
smallFont = getFont().deriveFont(Font.BOLD, 18);
}
void drawStartScreen(Graphics2D g) {
g.setColor(Color.red);
g.setFont(smallFont);
g.drawString("hit it", 1150/2, 190);
g.drawString("(click to start)", 1150/2, 240);
}
public void paintComponent(Graphics gg) {
super.paintComponent(gg);
Graphics2D g = (Graphics2D) gg;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
drawStartScreen(g);
}
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("hit it");
f.setResizable(false);
f.add(new hitit(), BorderLayout.CENTER);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
There's so much wrong with this code I don't even know where to begin.
I guess for a start this mess won't compile. public hitit() is clearly missing a return type, and it's impossible to say what component are you using there and where does public void paintComponent(Graphics2D gg) method belong.
In general though the whole approach seems to be wrong - why do you want to draw text manually instead of using an available component like javax.swing.JLabel?

java Swing button action

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();
}
}
}

Set Transparent Color for the Whole JPanel

I have a JPanel with a JLabel which owns an Icon picture.
how do I set a transparent red color at the top of the whole JPanel (including JLabel Icon)?
I have the transparent backgriound color on for the panel but I want the whole panel including the picture and everything get this transparent color. something like a transparent colorful glass at the top of the JPanel
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class TransparentJLabel {
private static final String IMAGE_PATH = "http://duke.kenai.com/Oracle/OracleStratSmall.png";
private static void createAndShowUI() {
JPanel panel = new JPanel();
panel.setBackground(Color.pink);
URL imageUrl;
try {
imageUrl = new URL(IMAGE_PATH);
BufferedImage image = ImageIO.read(imageUrl);
ImageIcon icon = new ImageIcon(image);
JLabel label = new JLabel(icon);
panel.add(label);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
JFrame frame = new JFrame("TransparentJLabel");
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
If you just need a layered panel over the whole contentPane, a simple glassPane will do fine (override it's paintComponent(...) method). For example:
JPanel glassPane = new JPanel() {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(new Color(0, 100, 0, 100));
g2.fillRect(0, 0, getWidth(), getHeight());
g2.dispose();
}
};
glassPane.setOpaque(false);
frame.setGlassPane(glassPane);
frame.getGlassPane().setVisible(true);
However, if you want a layered panel over only one JPanel, I would use JLayer combined with LayerUI, as MadProgrammer already mentioned. You will need a custom LayerUI in which you override the paint(Graphics g, JComponent c) method. I know that sounds dangerous, but I honestly don't know of another way of doing it...
I've provided an example below, this is the output:
As you can see, panel1 (or more accurately, the JLayer) is slighty transparent (RGBA = "0, 100, 0, 100") and panel2 is normal.
Code:
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
import javax.swing.plaf.LayerUI;
public class Example {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Example();
}
});
}
public Example() {
JFrame frame = new JFrame("Example");
JPanel panel1 = new JPanel();
panel1.add(new JButton("Panel 1"));
MyLayerUI layerUI = new MyLayerUI();
JLayer<JPanel> panel1Layer = new JLayer<JPanel>(panel1, layerUI);
panel1.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
if (layerUI.hasOverlay()) {
layerUI.setOverlay(false);
} else {
layerUI.setOverlay(true);
}
panel1Layer.repaint();
}
});
JPanel panel2 = new JPanel();
panel2.add(new JButton("Panel 2"));
JPanel contentPane = new JPanel(new GridLayout(2, 1));
contentPane.add(panel1Layer);
contentPane.add(panel2);
frame.setContentPane(contentPane);
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class MyLayerUI extends LayerUI<JPanel> {
private boolean overlay = true;
#Override
public void paint(Graphics g, JComponent c) {
super.paint(g, c);
if (hasOverlay()) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(new Color(0, 100, 0, 100));
g2.fillRect(0, 0, c.getWidth(), c.getHeight());
g2.dispose();
}
}
public boolean hasOverlay() {
return overlay;
}
public void setOverlay(boolean overlay) {
this.overlay = overlay;
}
}

How to make JFrame paint only after I click button?

When I run the application the whole frame is painted black.
How can I make it so that it starts out clear then it gets painted when I press the button?
package card;
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 BdayCard extends JFrame {
JButton button1, button2;
JPanel panel;
BdayCard()
{
panel = new JPanel();
button1 = new JButton();
button1.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
repaint();
}
});
panel.add(button1);
this.add(panel);
this.setTitle("It's Your Birthday!");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(600, 450);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
public void paint(Graphics g){
g.fillRect(0, 0, 600, 450);
}
public static void main(String[] args){
new BdayCard();
}
}
your problem with your blackscreen is because you paint at:
g.fillRect(0, 0, 600, 450);
you are using the default colour which is black
I tried your code and used this:
g.setColor(Color.WHITE);
this clears your screen and then use a boolean and set it true when your button is pressed:
public void actionPerformed(ActionEvent e)
{
button=true;
repaint();
}
then finally use:
if(button){/*do stuff here*/}
in the paint method

Inserting an image under a JTextArea

so I'm trying to insert an image underneath a JTextArea, but I havent had much luck, could anyone please help? Basically what I'm asking is if anybody could help make another class or subclass that does this. Heres my code:
import java.awt.*;
import javax.swing.*;
public class t{
private JFrame f; //Main frame
private JTextArea t; // Text area private JScrollPane sbrText; // Scroll pane for text area
private JButton btnQuit; // Quit Program
public t(){ //Constructor
// Create Frame
f = new JFrame("Test");
f.getContentPane().setLayout(new FlowLayout());
String essay = "Test";
// Create Scrolling Text Area in Swing
t = new JTextArea(essay, 25, 35);
t.setEditable(false);
Font f = new Font("Verdana", Font.BOLD, 12 );
t.setFont( f );
t.setLineWrap(true);
sbrText = new JScrollPane(t);
sbrText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
// Create Quit Button
btnQuit = new JButton("Quit");
btnQuit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.exit(0);
} } );
}
public void launchFrame(){ // Create Layout
// Add text area and button to frame
f.getContentPane().add(sbrText);
f.getContentPane().add(btnQuit);
// Close when the close button is clicked
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Display Frame
f.pack(); // Adjusts frame to size of components
f.setSize(450,480);
f.setResizable(false);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String args[]){
t gui = new t();
gui.launchFrame();
}
}
The basic issue is that JTextArea will paint it's background and it's text within the paintComponent.
The simplest solution is to make the JTextArea transparent and take over the control of painting the background.
This example basically fills the background with the background color, paints the image and then calls super.paintComponent to allow the text to be rendered.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TransparentTextArea {
public static void main(String[] args) {
new TransparentTextArea();
}
public TransparentTextArea() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(new CustomTextArea()));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class CustomTextArea extends JTextArea {
private BufferedImage image;
public CustomTextArea() {
super(20, 20);
try {
image = ImageIO.read(new File("/Users/swhitehead/Dropbox/MegaTokyo/Miho_Small_02.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public boolean isOpaque() {
return false;
}
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(getBackground());
g2d.fillRect(0, 0, getWidth(), getHeight());
if (image != null) {
int x = getWidth() - image.getWidth();
int y = getHeight() - image.getHeight();
g2d.drawImage(image, x, y, this);
}
super.paintComponent(g2d);
g2d.dispose();
}
}
}
Check out the Background Panel. When you add a scrollpane to the panel it will make the scrollpane, viewport and text area all non-opaque so you can see the image.

Categories