how to simply implement a KeyListener? - java

public class MyPanel extends JPanel implements KeyListener {
private char c = 'e';
public MyPanel() {
this.setPreferredSize(new Dimension(500,500));
addKeyListener(this);
}
public void paintComponent(Graphics g) {
super.repaint();
g.drawString("the key that pressed is" + c, 250,250);
}
public void keyPressed(KeyEvent e) {
c=e.getKeyChar();
repaint();
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
c=e.getKeyChar();
repaint();
}
public static void main(String[] s) {
JFrame f=new JFrame();
f.getContentPane().add(new MyPanel());
f.pack();
f.setVisible(true);
}
}
I tried reading this yet didnt mange to understand how to simply implement a KeyListener. so what do i need to change for this to work?

Here are the reasons why it doesn't work:
The JPanel does not have the keyboard focus. (The frame has it.) You probably want to requestFocus when the panel is added to the screen.
You need to call repaint when the graphic should change.
You mustn't call repaint in the paintComponent method.
You need to clear the drawing area before drawing the string again (otherwise all characters will end up on top of each other).
Here's a complete working example:
class MyPanel extends JPanel implements KeyListener {
private char c = 'e';
public MyPanel() {
this.setPreferredSize(new Dimension(500, 500));
addKeyListener(this);
}
public void addNotify() {
super.addNotify();
requestFocus();
}
public void paintComponent(Graphics g) {
g.clearRect(0, 0, getWidth(), getHeight());
g.drawString("the key that pressed is " + c, 250, 250);
}
public void keyPressed(KeyEvent e) { }
public void keyReleased(KeyEvent e) { }
public void keyTyped(KeyEvent e) {
c = e.getKeyChar();
repaint();
}
public static void main(String[] s) {
JFrame f = new JFrame();
f.getContentPane().add(new MyPanel());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
}
Oh, and you may want to add f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) to make the application terminate when you close the window. :-)

Related

Gui graphic does not appear in Panel

I am trying to make a drawOval moving by using the two buttons that I set to be North and East so the ball will move between the JButtons, at the center.
Why does not appear at the panel?
Also I am thinking using a function that make this x=x+; and y=y+1 when I pressed left or right.
I do not figure out what can I do.
So this is the code I made:
public class Main extends JFrame implements ActionListener {
JButton left;
JButton right;
JPanel p;
Main(){
JButton left = new JButton("left");
left.addActionListener(this);
left.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
//The first way I think is better to make it move.
}
});
JButton right = new JButton("right");
right.addActionListener(this);
Panel p = new Panel();
p.setLayout(new BorderLayout());
p.add("West",left);// to the left
p.add("East",right);//to the right
Container c = getContentPane();
c.add(p);
}
public static void main(String[] args) {
Main f=new Main();
f.setTitle("Heracles");
f.setSize(500, 500);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true); //this is the window
}
public void paintComponent (Graphics g) {
super.paintComponents(g);
Graphics2D g1=(Graphics2D) g;
g.drawOval(3, 5, 45, 46); // The ball
g.fillOval(20, 30, 40, 40);
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
To understand why it's not working, you need to understand how the paint system actually works
Just by looking at this snippet it should be obvious something is wrong.
public class Main extends JFrame implements ActionListener {
//...
public void paintComponent (Graphics g) {
super.paintComponents(g);
//...
}
}
You've declare a method called paintComponent but are calling the super method paintComponents (note the s at the end).
Further, when ever you "think" you're overriding a method, you should make use of the #Override attribute, this will cause a compiler error when you've done something wrong
public class Main extends JFrame implements ActionListener {
//...
#Overrride
public void paintComponent (Graphics g) {
super.paintComponents(g);
//...
}
}
The above code will now fail to compile, as JFrame doesn't declare a paintComponent method.
As a general rule, you should avoid extending directly from JFrame (or other top level containers), they are compound components and have a complex hierarchy and functionality.
A better place to start might be with a JPanel
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
JButton left;
JButton right;
JPanel paintPane;
public TestPane() {
JButton left = new JButton("left");
left.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
}
});
JButton right = new JButton("right");
right.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
}
});
paintPane = new PaintPane();
setLayout(new BorderLayout());
add(left, BorderLayout.WEST);
add(right, BorderLayout.EAST);
add(paintPane);
}
}
public class PaintPane extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
public void paintComponent(Graphics g) {
super.paintComponents(g);
Graphics2D g1 = (Graphics2D) g;
g1.drawOval(3, 5, 45, 46); // The ball
g1.fillOval(20, 30, 40, 40);
}
}
}
You should take the time to have a look at Painting in Swing and Performing Custom Painting for more details.
Some other concepts you might like to take the time to learn:
Single Responsibility Principle - a class should do one thing and do it well
Observer Pattern - This typically represent in Swing as the listener API
Model-View-Controller - this encompasses the above and defines different layers of responsibility for different parts of the program, it will helper you understand the basic structure of Swing as well
Also I am thinking using a function that make this x=x+; and y=y+1 when I pressed left or right.
Ok, so this is where the "model" part of the MVC will play it's part.
So lets start by defining the basic properties we expect the model to support...
public interface ShapeModel {
public Point getPoint();
public void addChangeListener(ChangeListener listener);
public void removeChangeListener(ChangeListener listener);
}
Here is supports a Point to act as the location and a ChangeListener to act as the observer pattern, which will notify interested parties that the state of the model has changed.
Why start with a interface? As a general concept, you should always prefer to code to interface instead of implementation. In this case, one aspect of the interface which hasn't been defined is, how does the Point get updated? That's of little interest to most parties who want to work with the model, they just want to know when it changes, the mutation of the model can be expressed either directly via the implementation or a "mutable" interface which extends from the this interface
Next, we define a default implementation...
public class DefaultShapeModel implements ShapeModel {
private Point point = new Point(40, 40);
private List<ChangeListener> listeners = new ArrayList<>(25);
#Override
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
fireStateChanged();
}
protected void fireStateChanged() {
ChangeEvent evt = new ChangeEvent(this);
for (ChangeListener listener : listeners) {
listener.stateChanged(evt);
}
}
#Override
public void addChangeListener(ChangeListener listener) {
listeners.add(listener);
}
#Override
public void removeChangeListener(ChangeListener listener) {
listeners.remove(listener);
}
}
This does define how the paint is to be updated.
Finally, we update the TestPane and PaintPane to support the model...
public class TestPane extends JPanel {
JButton left;
JButton right;
JPanel paintPane;
private DefaultShapeModel model;
public TestPane() {
model = new DefaultShapeModel();
JButton left = new JButton("left");
left.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
Point p = model.getPoint();
p.x--;
if (p.x > 0) {
p.x = 0;
}
model.setPoint(p);
}
});
JButton right = new JButton("right");
right.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Point p = model.getPoint();
p.x++;
if (p.x + 40 > paintPane.getWidth()) {
p.x = paintPane.getWidth() - 40;
}
model.setPoint(p);
}
});
paintPane = new PaintPane(model);
setLayout(new BorderLayout());
add(left, BorderLayout.WEST);
add(right, BorderLayout.EAST);
add(paintPane);
}
}
public class PaintPane extends JPanel {
private ShapeModel model;
public PaintPane(ShapeModel model) {
this.model = model;
this.model.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
repaint();
}
});
}
public ShapeModel getModel() {
return model;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
public void paintComponent(Graphics g) {
super.paintComponents(g);
Graphics2D g1 = (Graphics2D) g;
Point p = getModel().getPoint();
g1.fillOval(p.x, p.y, 40, 40);
g1.setColor(Color.WHITE);
g1.drawOval(p.x, p.y, 40, 40);
}
}
Why does not appear at the panel?
To display graphic you created, use follow these steps,
Remove paintComponent method and replace it with below code..
public JComponent createOvel() {
return new JComponent() {
#Override
protected void paintComponent(Graphics g) {
Graphics2D g1 = (Graphics2D) g;
g.drawOval(3, 5, 45, 46); // The ball
g.fillOval(20, 30, 40, 40);
}
};
}
Then call it in Main() constructor,
p.add("Center", createOvel());
This will display the graphic you created.

Want to create a frame taking mouse input and implements drawLines()

I am trying to create a frame that is taking input from mouse and also make x/o grid on frame using drawLines(). But I am able to do only one of the two.
Here is my code:
public class Test extends JPanel {
public static void main(String[] args) {
Test t = new Test();
t.dispFrame();
}
public static void dispFrame()
{
JFrame frame = new JFrame("My New Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(300, 300));
frame.setResizable(false);
JPanel panel=new JPanel();
panel.addMouseListener(new MouseListener()
{
#Override
public void mouseClicked(MouseEvent e) {
System.out.println(":MOUSE_CLICK_EVENT:");
}
#Override
public void mousePressed(MouseEvent e) {
System.out.println("\n:MOUSE_PRESSED_EVENT:");
}
#Override
public void mouseReleased(MouseEvent e) {
System.out.println(":MOUSE_RELEASED_EVENT:");
}
#Override
public void mouseEntered(MouseEvent e) {
System.out.println(":MOUSE_ENTER_EVENT:");
}
#Override
public void mouseExited(MouseEvent e) {
System.out.println(":MOUSE_EXITED_EVENT:");
}
});
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawLine(30,100,270,100);
g.drawLine(30,200,270,200);
g.drawLine(100,35,100,250);
g.drawLine(200,35,200,250);
}
}
If you want to override the paintComponent() method on your panel, you should do something like this,
JPanel panel = new JPanel() {
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawLine(30,100,270,100);
g.drawLine(30,200,270,200);
g.drawLine(100,35,100,250);
g.drawLine(200,35,200,250);
}
};
In your code, your are overriding the paintComponent() in your Test class, which will throw a compile time error if your Test class itself is not a subclass Component.

Draw 2D graphics object on Click base

Here is my code below. It draw triangles on execution. I want to make a little change in it.
Change is
On execution there would be 1 triangle. but if i Click inside the triangle 1 then it draw other triangle. else dont draw.
I tried to do with the changes in g2d.draw(triangle2);
But it have problem. It just dont show triangle but draw it as hidden.
public class Triangle_shape extends JFrame implements ActionListener {
public static int x=0;
public static JButton btnSubmit = new JButton("Submit");
public static JButton change = new JButton("Change");
public Triangle_shape(){
}
public static void main(String[] args) {
TrianglePanel t= new TrianglePanel();
ClickListener cl= new ClickListener();
JFrame frame = new JFrame ();
final int FRAME_WIDTH = 500;
final int FRAME_HEIGHT = 500;
btnSubmit.addActionListener(cl);
frame.setSize (FRAME_WIDTH, FRAME_HEIGHT);
frame.setLayout(new BorderLayout());
frame.add(new TrianglePanel(), BorderLayout.CENTER);
frame.add(btnSubmit, BorderLayout.PAGE_END);
frame.add(change, BorderLayout.LINE_END);
frame.pack();
frame.repaint();
frame.setTitle("A Test Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static class TrianglePanel extends JPanel implements MouseListener{
private Polygon triangle,triangle2;
public TrianglePanel(){
//Create triangle
System.out.println("From Draw "+x);
triangle = new Polygon();
triangle.addPoint(150, 200);
triangle.addPoint(100, 100);
triangle.addPoint(200, 100);
triangle2 = new Polygon();
triangle2.addPoint(200, 300);
triangle2.addPoint(200, 200);
triangle2.addPoint(300, 200);
//Add mouse Listener
addMouseListener(this);
//Set size to make sure that the whole triangle is shown
setPreferredSize(new Dimension(300, 300));
}
/** Draws the triangle as this frame's painting */
public void paintComponent(Graphics g){
Graphics2D g2d = (Graphics2D)g;
System.out.println("From Graphics "+x);
g2d.draw(triangle);
g2d.draw(triangle2);
}
//Required methods for MouseListener, though the only one you care about is click
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
/** Called whenever the mouse clicks. */
public void mouseClicked(MouseEvent e) {
x++;
Point p = e.getPoint();
if(triangle.contains(p) )
System.out.println("1");
else if (triangle2.contains(p))
{ System.out.println("2");
}
else
{
System.out.println("Trianglhhhhhhhhhhhhhhhhhhpoint");
x--;}
}
}
private static class ClickListener implements ActionListener {
private int clickCount = 0;
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btnSubmit) {
clickCount++;
if (clickCount == 1)
btnSubmit.setText("clicked!");
else
btnSubmit.setText("Inside Triangle " + x + " times!");
}
else {
//JOptionPane.showMessageDialog(MainClass.this, "You must click at least once!",
btnSubmit.setText("Error " + clickCount + " times!");
}
}
}
}
Try the below code, its a sample created from your own code.
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class MyTriangle{
static JFrame frame = new JFrame();
public static void main(String[] args)
{
frame.setSize(1000, 1500);
frame.setTitle("Triangle Draw");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//add panel to frame and make it visible
Polygon triangle1 = new Polygon();
triangle1.addPoint(100, 500); // first
triangle1.addPoint(600, 500);//last
triangle1.addPoint(350, 300);//middel
addTriangle(new Triangle(triangle1));
frame.setVisible(true);
}
public static void addTriangle(Triangle triangle1)
{
frame.add(triangle1);
}
static class Triangle extends JPanel implements MouseListener{
private Polygon triangle;
public Triangle(Polygon triangle)
{
this.triangle = triangle;
addMouseListener(this);
}
public void paintComponent(Graphics g){
Graphics2D g2d = (Graphics2D)g;
g2d.draw(triangle);
}
#Override
public void mouseClicked(MouseEvent e) {
Point p = e.getPoint();
if(triangle.contains(p))
{
Polygon triangle2 = new Polygon();
triangle2.addPoint(200, 300);
triangle2.addPoint(200, 200);
triangle2.addPoint(300, 200);
MyTriangle.addTriangle(new Triangle(triangle2));
Graphics2D g2d = (Graphics2D)this.getGraphics();
g2d.draw(triangle2);
}
}
}
}

Jbutton that draws on a new Jpanel

i'd like this button to (on click) draw an Oval. Problem is that eclipse says something about missing semicolons (in the action listener definition) and i dont understand why. Whats the proper way of passing methods (bulid in or custom) to the action listeners?
public class figury implements ActionListener {
public figury() {
frame();
}
public void frame() {
JFrame f = new JFrame();
f.setVisible(true);
f.setSize(480, 480);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel p = new JPanel();
JButton kolo = new JButton("Rysuj kolo");
JButton kolo = new JButton("Rysuj kwadrat");
kwadrat.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
public void paintComponent(Graphics g){
g.fillOval(50,50,100,100);
g.setColor(Color.RED);
}
}
});
p.add(kolo);
f.add(p);
}
public static void main(String[] args) {
new figury();
}
}
You are trying to define a method inside another method there. In your case, the problem is in the line containing
public void paintComponent(Graphics g) {
...
This cannot be defined inside another method in java. There are good ideas for painting in java in these official documentation links and stackoverflow questions:
How to make canvas with Swing?
http://www.oracle.com/technetwork/java/painting-140037.html
If your figury class implements ActionListener, it should implement public void actionPerformed(ActionEvent e) method.
Also you are trying to declare a method paintComponent() inside another actionPerformed() method.
I think your code should look something like this:
public class figury implements ActionListener {
public figury() {
frame();
}
public void frame() {
JFrame f = new JFrame();
f.setVisible(true);
f.setSize(480, 480);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel p = new JPanel();
JButton kolo = new JButton("Rysuj kolo");
JButton kwadrat = new JButton("Rysuj kwadrat");
kwadrat.addActionListener(this);
p.add(kolo);
p.add(kwadrat);
f.add(p);
}
#Override
public void actionPerformed(ActionEvent e) {
paintComponent(/*pass here a Graphics object*/);
}
public void paintComponent(Graphics g) {
g.fillOval(50,50,100,100);
g.setColor(Color.RED);
}
public static void main(String[] args) {
new figury();
}
}

How to make a transparent JFrame but keep everything else the same?

I want to make the JFrame transparent, but the image on top of it to be non-transparent. This is what I have now:
Does anyone know a way to make only the JFrame transparent?
Here's my code:
import javax.swing.*;
import java.awt.*;
import com.sun.awt.AWTUtilities;
import static java.awt.GraphicsDevice.WindowTranslucency.*;
public class SplashDemo extends JFrame
{
public SplashDemo()
{
setUndecorated(true);
setSize(200, 200);
add(new JLabel(new ImageIcon("puppy2.png")));
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
setOpacity(0.85f);
}
public static void main(String[] args)
{
new SplashDemo();
}
}
Basically, you need to make a transparent window and a translucent content pane. This will mean anything added to the content pane will continue to be rendered without additional alphering...
public class TranscluentWindow {
public static void main(String[] args) {
new TranscluentWindow();
}
public TranscluentWindow() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JWindow frame = new JWindow();
frame.setAlwaysOnTop(true);
frame.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
SwingUtilities.getWindowAncestor(e.getComponent()).dispose();
}
}
});
frame.setBackground(new Color(0,0,0,0));
frame.setContentPane(new TranslucentPane());
frame.add(new JLabel(new ImageIcon(ImageIO.read(getClass().getResource("/Puppy.png")))));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class TranslucentPane extends JPanel {
public TranslucentPane() {
setOpaque(false);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(0.85f));
g2d.setColor(getBackground());
g2d.fillRect(0, 0, getWidth(), getHeight());
}
}
}

Categories