I just made this program that I add a button on my panel, but I am not able to move on to use actionListener to make the button work. Their should be pictures appered on the panel and when the button clicked, the picture should change to another picture. Please help me, thanks! Here is my code.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class DrawPanelThree extends JPanel
{
private JButton button;
public DrawPanelThree()
{
button = new JButton();
setLayout(new BorderLayout());
add(button, BorderLayout.SOUTH);
button.setText("Start");
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawRect(90, 40, 100, 50);
g.setColor(Color.RED);
g.fillRect(10, 10, 10, 10);
g.fillRect(260, 10, 10, 10);
g.fillRect(10, 120, 10, 10);
g.fillRect(260, 120, 10, 10);
g.setColor(new Color(255, 215, 0));
g.fillOval(120, 45, 40, 40);
}
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setTitle("Rectangle");
frame.setSize(new Dimension(300, 200));
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawPanelThree panel = new DrawPanelThree();
frame.add(panel);
panel.setBackground(Color.CYAN);
frame.setVisible(true);
}
private class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
}
}
}
You have to add the ActionListener to the button, like so:
button.addActionListener(new MyCoolActionListener());
You can also define the ActionListener when you declare it, but that's the general idea. You want to add the ActionListener soon after you declare the JButton, in your constructor.
Hope this helps!
Related
My question is how to display buttons on top of a circle which created with Graphics. My code is :
public class Grafik extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Grafik frame = new Grafik();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Grafik() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 784, 419);
JPanel contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JButton btnNewButton = new JButton("Click");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
fire();
}
});
btnNewButton.setBounds(64, 73, 32, 32);
contentPane.add(btnNewButton);
}
public void fire()
{
JPanel panel = new JPanel(){
#Override
public void paint(Graphics g)
{
g.setColor(Color.black);
g.drawOval(20, 20, 400, 400);
g.fillOval(20,20,400,400);
g.setColor(Color.white);
g.drawOval(60, 60, 300, 300);
g.fillOval(60,60,300,300);
}
};
panel.setBounds(10, 27, 383, 233);
setContentPane(panel);
JButton btn = new JButton();
btn.setIcon(new ImageIcon("C:\\Users\\nuria\\Desktop\\icon1.png"));
btn.setBounds(75, 76, 32, 32);
panel.add(btn);
}
}
This code is a little part of my project. I have a lot of panels in my project and my fire method isn't called firstly. I mean the fire method is called by sixth panel. I have to draw two circles with buttons. These buttons should be between two circles. But i cant display buttons directly. When i hover the buttons, they show. I want to show buttons instantly when the sixth panel opens.
I have two buttons above. When the first button is clicked, another panel should open and show circles(which created with Graphics) and another button(with a icon) between them.
JPanel panel = new JPanel(){
#Override
public void paint(Graphics g)
{
Don't override paint(). Custom painting is done by overriding paintComponent() and don't forget to invoke super.paintComponent() as the first statement.
The problem with your current code is that by overriding paint you have changed the default painting logic of the panel and the child components are never painted.
Take a look at the section from the Swing tutorial on Custom Painting for more information and examples, especially the section on A Closer Look at the Paint Mechanism.
I am trying to make a JFrame display a different JPanel when a specific tab is selected. I have tried adding code to make it add the new panel based on which tab index is selected.
Where am I going wrong with this? What do I need to add to make it work? Thanks.
EDIT
Here is my solved SSCCE:
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
public class MainPanel {
private static JTabbedPane tabbedPane = new JTabbedPane();
private static JFrame frame = new JFrame("Testing");
public static void main(String[] args) {
EventQueue.invokeLater(MainPanel::createAndShowGUI);
}
protected static void createAndShowGUI()
{
DrawGraphics drawGraphics = new DrawGraphics();
DrawDifferentGraphics drawDifferentGraphics = new DrawDifferentGraphics();
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(tabbedPane, BorderLayout.WEST);
tabbedPane.addTab("CFG", null);
tabbedPane.addTab("CNX", null);
frame.add(drawGraphics);
tabbedPane.addChangeListener(e -> {
if (tabbedPane.getSelectedIndex() == 0) {
frame.remove(drawDifferentGraphics);
frame.add(drawGraphics);
frame.validate();
frame.repaint();
}
if (tabbedPane.getSelectedIndex() == 1) {
frame.remove(drawGraphics);
frame.add(drawDifferentGraphics);
frame.validate();
frame.repaint();
}});
frame.setLocationByPlatform(true);
frame.setSize(400, 400);
frame.setVisible(true);
}
}
class DrawGraphics extends JPanel {
private ArrayList<Shape> shapes = new ArrayList<Shape>();
public DrawGraphics() {
setLayout(new BorderLayout());
shapes.add(new Ellipse2D.Double(10, 10, 20, 20));
shapes.add(new Ellipse2D.Double(10, 30, 20, 20));
shapes.add(new Ellipse2D.Double(10, 50, 20, 20));
shapes.add(new Ellipse2D.Double(10, 70, 20, 20));
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g.create();
g2d.setColor(Color.BLUE);
shapes.forEach(g2d::fill);
g2d.dispose();
}
}
class DrawDifferentGraphics extends JPanel {
private ArrayList<Shape> shapes = new ArrayList<Shape>();
public DrawDifferentGraphics() {
setLayout(new BorderLayout());
shapes.add(new Rectangle2D.Double(10, 10, 10, 10));
shapes.add(new Rectangle2D.Double(10, 30, 10, 10));
shapes.add(new Rectangle2D.Double(10, 50, 10, 10));
shapes.add(new Rectangle2D.Double(10, 70, 10, 10));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g.create();
g2d.setColor(Color.RED);
shapes.forEach(g2d::fill);
g2d.dispose();
}
}
I want to display the graphics on the panel next to the tabbedPane.
Read the section from the Swing tutorial on How to Write a ChangeListener.
You will be notified when a tab has been clicked. You then get the selected tab and add the panel to the frame.
So basically your if (tabbedPane.getSelectedIndex() == 0) logic would be moved to the ChangeListener.
Or instead of having a bunch of "if statement" you could have a Map of Integer/JPanel values. Then you just get the index and get the panel from the Map.
Once you add the panel to the frame you then need to revalidate() and repaint() the frame.
Edit:
Actually the above suggestion is not complete. You can't just keep adding panels to the frame. The CENTER area of the BorderLayout should only contain a single component, otherwise you can get painting problems.
This can be demonstrated by clicking on the unselected tab, and then resize the frame. The original panel will be displayed.
You need to do one of the following:
Use a CardLayout (read the tutorial if you haven't used layout before) on a penel in the CENTER of the BordreLayout. So in this case the panel using the CardLayout is the only component in the CENTER and then it manages the panel that is displayed in the CardLayout. So your ChangeListener would need to identify the card to be displayed. You could set the card identifier to be the text of the selected tab. So
Remove the current panel BEFORE adding the new panel. In this case there is only a single panel in the CENTER so painting is as expected.
I have problem with adding Label by constructor, when I make it by method it's no problem
private void addLabel() {
System.out.println("asd");
JLabel label = new JLabel("asd");
label.setBounds(10, 40, 100, 25);
add(label);
repaint();
validate();
System.out.println("asd2");
}
But when i try to do this same by new class and constructor i doesn't work...
Main frame:
public class Frame extends JFrame {
JButton button = new JButton("new");
AddButton button2 = new AddButton();
public Frame() {
setLayout(null);
setSize(400, 500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
button.setBounds(40, 10, 50, 25);
add(button);
button2.setBounds(40, 40, 100, 25);
add(button);
}
public static void main(String[] args) {
Frame ap = new Frame();
ap.setVisible(true);
}
AddButton class:
public class AddButton extends JPanel {
JLabel label = new JLabel("asd");
public AddButton() {
label.setBounds(10, 40, 100, 25);
add(label);
repaint();
validate();
}
}
Ok i got it, I tried to add "button" two times istead button and button2 :D
Your constructor doesn't make sense, that's not how you should use constructors - constructors are used to create an instance of a class.
When you write
AddButton button2 = new AddButton();
then button2 is of type AddButton, and add doesn't accept this type of object.
You can Edit like this
public class AddButton extends JPanel {
JLabel label;
public AddButton() {
label=new JLabel("asd");
label.setBounds(10, 40, 100, 25);
add(label);
repaint();
validate();
}
}
I am working on a little menu program with clickable buttons and an image that changes based on button clicks. If I click a button I get a shadow of the button at the bottom where I change the JLabel text. I cannot figure it out for the life of me. Any advice would be greatly appreciated. Visuals below...thanks
public class SampleGUI
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
System.out.println("Created GUI on EDT? " +
SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("Robert's VICI Prototype");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new MyPanel());
f.pack();
f.setVisible(true);
}
}
class MyPanel extends JPanel
{
// Fields
Image imageDisplayed;
JLabel status;
// Methods
public MyPanel()
{
setBorder(BorderFactory.createLineBorder(Color.BLACK));
setLayout(null);
JLabel title = new JLabel("CS380 TEAM 5 VICI Prototype");
title.setFont(new Font("Tahoma", Font.BOLD, 20));
title.setBounds(425, 10, 400, 40);
add(title);
status = new JLabel("Please click an option above.");
status.setFont(new Font("Tahoma", Font.BOLD, 14));
status.setBounds(425, 740, 400, 40);
add(status);
JButton choice1 = new JButton("Search Class");
choice1.setBounds(50, 50, 150, 40);
add(choice1);
JButton choice2 = new JButton("Add Class");
choice2.setBounds(225, 50, 150, 40);
add(choice2);
JButton choice3 = new JButton("Drop Class");
choice3.setBounds(400, 50, 150, 40);
add(choice3);
JButton choice4 = new JButton("Verify Reg Hold");
choice4.setBounds(575, 50, 150, 40);
add(choice4);
JButton choice5 = new JButton("Verify Reg Date");
choice5.setBounds(750, 50, 150, 40);
add(choice5);
JButton choice6 = new JButton("Schedule Advisor");
choice6.setBounds(925, 50, 150, 40);
add(choice6);
choice6.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
System.out.println("Schedule Advisor button pressed.");
status.setText("Choose a date.");
imageDisplayed = new ImageIcon("C:\\Temp\\sa01.jpg").getImage();
}
});
JButton exit = new JButton("EXIT");
exit.setBounds(940, 750, 150, 40);
add(exit);
exit.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
imageDisplayed = new ImageIcon("C:\\Temp\\main.jpg").getImage();
}
#Override
public Dimension getPreferredSize()
{
return new Dimension(1100, 800);
}
#Override
public void paintComponent(Graphics g)
{
g.drawImage(imageDisplayed, 100, 120, 900, 600, this);
}
}
You've broken the paint chain...
#Override
public void paintComponent(Graphics g)
{
g.drawImage(imageDisplayed, 100, 120, 900, 600, this);
}
The first thing you should be calling is super.paintComponent(g)
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(imageDisplayed, 100, 120, 900, 600, this);
}
The Graphics context is shared resource, meaning that the Graphics context you get has also been used to paint the other components that have also been painted. One of the jobs of paintComponent is to clear the Graphics context ready for the component to be painted (fill the background)
See Painting in AWT and Swing and Performing Custom Painting for more details
You should, also, avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify. See Why is it frowned upon to use a null layout in SWING? for more details...
Before you go all defensive over getting your screen laid out just nicely, you shouldn't be doing it this way. You controls should be laid out on separate containers (using appropriate layout managers) and you "drawing surface" should be it's own component. See Laying Out Components Within a Container for more details...
If you're still not convicned, take a look at Why setting setPreferredSize() on JFrame is bad? and java expandable JDialog for examples of differences between Mac and Windows
I know there is a way to extend a JLabel to paint 3D borders and a way to paint round borders, but how do you get both? Here is my code
protected void paintComponent(Graphics g) {
g.setColor(getBackground());
g.fillRoundRect(0, 0, getWidth()-1, getHeight()-1, 25, 25);
g.fill3DRect(10, 10, 30, 30, true);
super.paintComponent(g);
Use LineBorder with rounded corners or a variant of the TextBubbleBorder.
You refer this code to create Round Corner JLabel:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class RoundedLineBorder extends JPanel {
public RoundedLineBorder() {
super(true);
setLayout(new BorderLayout());
JLabel label = new JLabel("Rounded Corners");
label.setHorizontalAlignment(JLabel.CENTER);
LineBorder line = new LineBorder(Color.blue, 2, true);
label.setBorder(line);
add(label, BorderLayout.CENTER);
}
public static void main(String s[]) {
JFrame frame = new JFrame("Rounded Line Border");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 200);
frame.setContentPane(new RoundedLineBorder());
frame.setVisible(true);
}
}