I've made a custom subclass of JLabel. I have a single instance of this, inside a single JPanel, inside a single JFrame. I do not override the paintComponent() method; all the class does is change the background color when the cursor hovers over it.
The JFrame loads immediately, but for several seconds the JPanel is left undrawn. I verified that this is because of my custom class by overriding paintComponent() and adding some debug println() statements.
public void paintComponent(Graphics context)
{
System.out.println("Painting...");
super.paintComponent(context);
System.out.println("Painted.");
}
The strange thing is, it's drawn instantly when I use Panel instead of JPanel or Label instead of JLabel.
Where is this lag coming from?
EDIT: Some example code. Nothing is actually drawn; look at the console message delay.
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.awt.GridLayout;
import javax.swing.JPanel;
public class Example extends JLabel implements MouseListener
{
private static final long serialVersionUID = 0;
public Example()
{
super();
System.out.println("Constructed.");
}
public void paintComponent(java.awt.Graphics g)
{
System.out.println("Painting component...");
super.paintComponent(g);
System.out.println("Painted.");
}
public void mouseEntered(MouseEvent event) { }
public void mouseExited(MouseEvent event) { }
public void mouseReleased(MouseEvent event) { }
public void mousePressed(MouseEvent event) { }
public void mouseClicked(MouseEvent event) { }
public static void main(final String[] arguments)
{
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(1, 1));
panel.add(new Example());
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.setVisible(true);
System.out.println("Set visible.");
}
}
My code doesn't lag:
My SSCCE:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class LabelTest extends JPanel {
public LabelTest() {
add(new MyLabel("Fubar!"));
}
private static void createAndShowGui() {
LabelTest mainPanel = new LabelTest();
JFrame frame = new JFrame("LabelTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class MyLabel extends JLabel {
private static final Color BACKGROUND_DEFAULT = new Color(200, 200, 255);
private static final Color BACKGROUND_MOUSEOVER = new Color(255, 200, 200);
private static final int PREF_W = 200;
private static final int PREF_H = 100;
public MyLabel(String text) {
super(text, SwingConstants.CENTER);
setOpaque(true);
setBackground(BACKGROUND_DEFAULT);
addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent arg0) {
setBackground(BACKGROUND_MOUSEOVER);
}
#Override
public void mouseExited(MouseEvent e) {
setBackground(BACKGROUND_DEFAULT);
}
});
}
#Override
public Dimension getPreferredSize() {
int width = Math.max(super.getPreferredSize().width, PREF_W);
int height = Math.max(super.getPreferredSize().height, PREF_H);
return new Dimension(width, height);
}
}
This suggests to me that the problem isn't in the concept of a JLabel whose background changes via a MouseListener, but rather you've got a bug somewhere in your code. Where? Who knows until you post compilable runnable code, an SSCCE, like the one I've posted above.
Related
So I'm not sure what the problem is with the repaint method. It won't fill in a new background colour. It doesn't seem to print out a text within that method whenever I tried to debug it. I have 3 classes: GameInterface, Renderer, and RepaintConfiguration. The RepaintConfiguration extends from the GameInterface class and implements ActionListener.
public class GameInterface {
public static GameInterface gameInterface;
public static JFrame jframe;
private String title;
private Container container;
public GameInterface() {
gameInterface = this;
jframe = new JFrame();
jframe.setSize(1500, 800);
jframe.setResizable(false);
jframe.setTitle("Jetpack");
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setVisible(true);
}
}
public class Renderer extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
RepaintConfiguration.repaintConfiguration.repaint(g);
}
}
public class RepaintConfiguration extends GameInterface implements ActionListener
{
public static RepaintConfiguration repaintConfiguration;
public static Renderer renderer;
public static GameInterface gameInterface;
public RepaintConfiguration() {
super();
repaintConfiguration = this;
renderer = new Renderer();
super.jframe.add(renderer);
}
#Override
public void actionPerformed(ActionEvent e) {
renderer.repaint();
}
public void repaint(Graphics g) {
g.setColor(Color.red);
g.fillRect(0, 0, 1500, 800);
}
}
I managed to get your code to compile and run. Public classes have to be inner classes.
I added a main method. I added a call to the SwingUtilities invokeLater method. This method ensures that the Swing components are created and executed on the Event Dispatch Thread.
I reordered the JFrame method calls. The JFrame methods must be called in a specific order. This is the order I use for all my Swing applications.
You don't size the JFrame. You size the drawing JPanel. The JFrame includes decorations that take up some space.
I left your convoluted drawing code. You're going to have great difficulties extending this code to actually create a game.
Here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class GameInterface {
private JFrame jframe;
private Renderer renderer;
private RepaintConfiguration repaintConfiguration;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new GameInterface();
}
});
}
public GameInterface() {
this.repaintConfiguration = new RepaintConfiguration(this);
jframe = new JFrame();
jframe.setTitle("Jetpack");
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setResizable(false);
this.renderer = new Renderer(repaintConfiguration);
jframe.add(renderer, BorderLayout.CENTER);
jframe.pack();
jframe.setLocationByPlatform(true);
jframe.setVisible(true);
}
public Renderer getRenderer() {
return renderer;
}
public class Renderer extends JPanel {
private static final long serialVersionUID = 1L;
private RepaintConfiguration repaintConfiguration;
public Renderer(RepaintConfiguration repaintConfiguration) {
this.repaintConfiguration = repaintConfiguration;
this.setPreferredSize(new Dimension(1500, 800));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
repaintConfiguration.repaint(g);
}
}
public class RepaintConfiguration implements ActionListener {
private GameInterface gameInterface;
public RepaintConfiguration(GameInterface gameInterface) {
this.gameInterface = gameInterface;
}
#Override
public void actionPerformed(ActionEvent event) {
gameInterface.getRenderer().repaint();
}
public void repaint(Graphics g) {
g.setColor(Color.red);
g.fillRect(0, 0, 1500, 800);
}
}
}
So I've been working on a program and I wanted to make it borderless with jframe.setUndecorated(true);. However, I can't really move the JFrame window around the screen. Is there a way I can fix that?
Here is my current code for the JFrame:
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(700, 450);
frame.setLocationRelativeTo(null);
frame.setUndecorated(true);
frame.getContentPane().setBackground(Color.BLACK);
To move the JFrame, left-click inside the JFrame somewhere, drag the mouse to the new position, and release the mouse button when the JFrame is in the correct position.
Here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class MoveUndecoratedJFrame implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new MoveUndecoratedJFrame());
}
private JFrame frame;
#Override
public void run() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setUndecorated(true);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new FlowLayout());
MoveListener listener = new MoveListener();
panel.addMouseListener(listener);
panel.addMouseMotionListener(listener);
panel.setBackground(Color.BLACK);
panel.setPreferredSize(new Dimension(700, 400));
return panel;
}
public class MoveListener implements MouseListener, MouseMotionListener {
private Point pressedPoint;
private Rectangle frameBounds;
#Override
public void mouseClicked(MouseEvent event) {
}
#Override
public void mousePressed(MouseEvent event) {
this.frameBounds = frame.getBounds();
this.pressedPoint = event.getPoint();
}
#Override
public void mouseReleased(MouseEvent event) {
moveJFrame(event);
}
#Override
public void mouseEntered(MouseEvent event) {
}
#Override
public void mouseExited(MouseEvent event) {
}
#Override
public void mouseDragged(MouseEvent event) {
moveJFrame(event);
}
#Override
public void mouseMoved(MouseEvent event) {
}
private void moveJFrame(MouseEvent event) {
Point endPoint = event.getPoint();
int xDiff = endPoint.x - pressedPoint.x;
int yDiff = endPoint.y - pressedPoint.y;
frameBounds.x += xDiff;
frameBounds.y += yDiff;
frame.setBounds(frameBounds);
}
}
}
I have a Jframe with two buttons: '1' and '2'. Clicking the button '1' should display the capital letter A in the JPanel.
Code fore my JFrame:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class DrawFrame extends JFrame{
private final int WIDTH = 500;
private final int HEIGHT = 300;
private JButton number1;
private JButton number2;
private JPanel numberPanel;
private DrawPanel graphicsPanel;
public DrawFrame()
{
createSelectionPanel();
createGraphicsPanel();
this.setSize(WIDTH, HEIGHT);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
private void createSelectionPanel()
{
numberPanel = new JPanel();
number1 = new JButton("1");
number2 = new JButton("2");
numberPanel.setLayout(new GridLayout(2,2));
numberPanel.add(number1);
numberPanel.add(number2);
this.add(numberPanel, BorderLayout.WEST);
}
private void createGraphicsPanel()
{
//instantiate drawing panel
graphicsPanel = new DrawPanel();
//add drawing panel to right
add(graphicsPanel);
}
private class Number1ButtonListener implements ActionListener {
public void actionPerformed (ActionEvent event) {
Number number = new Number();
number.setNumber('A');
}
}
//creates a drawing frame
public static void main(String[] args)
{
DrawFrame draw = new DrawFrame();
}
}
Code for my JPanel
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
public class DrawPanel extends JPanel{
public Coordinates current;
public DrawPanel(){
//nothing drawn initially
current = null;
//set white background for drawing panel
setBackground(Color.WHITE);
//add mouse listeners
MouseHandler mouseHandler = new MouseHandler();
this.addMouseListener(mouseHandler);
this.addMouseMotionListener(mouseHandler);
}
public void paint(Graphics g){
super.paint(g);
if(current!=null){
I want to replace "A" with number.getNumber()
g.drawString("A", current.getX(), current.getY());
}
}
//class to handle all mouse events
private class MouseHandler extends MouseAdapter implements MouseMotionListener
{
public void mousePressed(MouseEvent event)
{
current = new Coordinates(event.getX(), event.getY());
}
public void mouseReleased(MouseEvent event)
{
repaint();
}
}
}
I'm not sure if this is possible. So sorry if I am mistaken in my logic. Please provide an alternate way for me to approach this problem. Appreciate any guidance.
Thanks!
The Coordinates and Number classes weren't included, so I had to modify the code somewhat.
Here's the GUI I created.
The first thing I did was create a model class for the GUI. By creating a model class, I could make the display string and the drawing coordinate available to the view and the controller classes. This is a simple example of the model / view / controller pattern.
package com.ggl.drawing;
import java.awt.Point;
public class GUIModel {
private String displayString;
private Point coordinate;
public GUIModel(String displayString) {
this.displayString = displayString;
}
public Point getCoordinate() {
return coordinate;
}
public void setCoordinate(int x, int y) {
this.coordinate = new Point(x, y);
}
public void setCoordinate(Point coordinate) {
this.coordinate = coordinate;
}
public void setDisplayString(String displayString) {
this.displayString = displayString;
}
public String getDisplayString() {
return displayString;
}
}
Now that we have a model, lets look at the DrawFrame class.
package com.ggl.drawing;
import java.awt.BorderLayout;
import java.awt.GridLayout;
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.SwingUtilities;
public class DrawFrame implements Runnable {
private final int WIDTH = 500;
private final int HEIGHT = 300;
private JFrame frame;
private GUIModel model;
public DrawFrame() {
this.model = new GUIModel("A");
}
#Override
public void run() {
frame = new JFrame("Draw Letters");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createSelectionPanel(), BorderLayout.WEST);
frame.add(new DrawPanel(WIDTH, HEIGHT, model), BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
private JPanel createSelectionPanel() {
JPanel numberPanel = new JPanel();
ButtonListener listener = new ButtonListener();
JButton number1 = new JButton("A");
number1.addActionListener(listener);
JButton number2 = new JButton("B");
number2.addActionListener(listener);
numberPanel.setLayout(new GridLayout(0, 2));
numberPanel.add(number1);
numberPanel.add(number2);
return numberPanel;
}
private class ButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent event) {
model.setDisplayString(event.getActionCommand());
}
}
// creates a drawing frame
public static void main(String[] args) {
SwingUtilities.invokeLater(new DrawFrame());
}
}
I started the Java Swing application on the Event Dispatch thread with the call to the SwingUtilities invokeLater method.
I separated the JFrame construction from the 2 JPanels construction. I used a JFrame, rather than extend a JFrame. The only time you should extend any Java class is if you want to override one or more of the class methods.
I used the same ButtonListener for both JButtons. I'm guessing what you want, but I drew either an "A" or a "B", depending on which button you left clicked.
Let's look at the DrawPanel class.
package com.ggl.drawing;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
public class DrawPanel extends JPanel {
private static final long serialVersionUID = 3443814601865936618L;
private GUIModel model;
public DrawPanel(int width, int height, GUIModel model) {
this.setPreferredSize(new Dimension(width, height));
this.model = model;
// add mouse listeners
MouseHandler mouseHandler = new MouseHandler();
this.addMouseListener(mouseHandler);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (model.getCoordinate() != null) {
Point p = model.getCoordinate();
Font font = g.getFont().deriveFont(48F);
g.setFont(font);
g.drawString(model.getDisplayString(), p.x, p.y);
}
}
// class to handle all mouse events
private class MouseHandler extends MouseAdapter {
#Override
public void mousePressed(MouseEvent event) {
model.setCoordinate(event.getPoint());
}
#Override
public void mouseReleased(MouseEvent event) {
DrawPanel.this.repaint();
}
}
}
The major change I made in this class was to use the paintComponent method, rather than the paint method. The paintComponent method is the correct method to override.
I set the size of the drawing panel in the DrawPanel constructor. It's much better to let Swing figure out the size of the JFrame. That's what the pack method in the DrawFrame run method does.
I increased the font size so you can see the drawn letter better.
I removed the mouse motion listener code, as it wasn't needed.
I hope this was helpful to you.
OK, all I know so far is that you want the text displayed in a JPanel to change if a button is pressed. If so, then your code looks to be way too complex for the job. Suggestions include:
Give the DrawingPanel a setter method, say, setText(String text), that allows outside classes to change the text that it displays.
Within that method, set a field of DrawingPanel, say called text, and call repaint().
Override DrawingPanel's paintComponent not its paint method, and call the super's method within your override.
Within the paintComponent method, call drawString to draw the String held by the text field, if the field is not null.
Give your buttons ActionListeners or AbstractActions that call the DrawingPanel's setText(...) method, setting the text to be displayed.
For example:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class DrawAorB extends JPanel {
private DrawingPanel drawingPanel = new DrawingPanel();
public DrawAorB() {
JPanel btnPanel = new JPanel(new GridLayout(1, 0, 5, 5));
btnPanel.add(new JButton(new ButtonAction("A")));
btnPanel.add(new JButton(new ButtonAction("B")));
setLayout(new BorderLayout());
add(drawingPanel, BorderLayout.CENTER);
add(btnPanel, BorderLayout.PAGE_END);
}
private class ButtonAction extends AbstractAction {
public ButtonAction(String name) {
super(name);
}
#Override
public void actionPerformed(ActionEvent e) {
String text = e.getActionCommand();
drawingPanel.setText(text);
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("DrawAorB");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new DrawAorB());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class DrawingPanel extends JPanel {
private static final int PREF_W = 200;
private static final int PREF_H = PREF_W;
private String text = null;
public void setText(String text) {
this.text = text; // set the JPanel's text
repaint(); // and draw it
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (text != null) {
int x = getWidth() / 2;
int y = getHeight() / 2;
// use FontMetrics if you want to center text better
g.drawString(text, x, y);
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
}
Even simpler, easier, and probably better would be to display the text within a JLabel as it's much easier to center this text.
I'm trying to display a string when a button is pressed, but it does not work. I do not know what the problem is. I get no error, but that does not bother me. I'm missing something fundamental, I suppose. Please help!!
//I'm trying to draw a string in the frame when a button is pressed, but it won't work..
//Can't figure out what the problem is.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class AppletTwo extends JFrame implements ActionListener
{
JFrame frameOne;
JButton btnOne;
AppletTwo()
{
frameOne = new JFrame("frameOne");
frameOne.setSize(320,240);
frameOne.setLayout(new FlowLayout(FlowLayout.LEFT));
frameOne.setVisible(true);
frameOne.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
btnOne = new JButton("Print");
btnOne.addActionListener(this);
frameOne.add(btnOne);
}
public void actionPerformed(ActionEvent ae)
{
if(ae.getSource() == btnOne)
{
repaint();
}
}
public void paint(Graphics g)
{
g.drawString("Never Works",150,150);
}
public static void main(String[] args)
{
AppletTwo frame1 = new AppletTwo();
}
}
" I'm missing something fundamental, I suppose. "
Yes, you are:
Main problem:
Your class is JFrame which is the component for which you are overriding the paint method. But you create another instance of a JFrame, which is the one you setVisible to. Keep in mind, you haven't drawn anything to this frame. So you are seeing the new instance of frame, not the class frame for which you are painting (and for which you never set visible).
Other problems:
You should always call super.paint[Component] after a paint[Component] override
#Override
public void paint(Graphics g) {
super.paint(g);
}
Don't paint on top level container like JFrame. Instead paint on a JPanel or JComponent and override is paintComponent method and call super.paintComponent, then add that component to the frame. See Performing Custom Painting
Swing apps should be run on the event dispatch thread (EDT). You can do so by wrapping your main code in a SwingUtilities.invokeLater(...). See Initial Threads
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
AppletTwo frame1 = new AppletTwo();
}
});
}
Generally, you always want to set the frame visible after adding your components.
Other notes:
See Extends JFrame vs. creating it inside the the program
UPDATE
Example with all the above mentioned points.
import java.awt.BorderLayout;
import java.awt.Dimension;
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;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class SimpleDrawing {
public SimpleDrawing() {
final DrawingPanel panel = new DrawingPanel();
final JTextField field = new JTextField(15);
JButton button = new JButton("Change name");
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
String someString = field.getText();
if (!someString.isEmpty()) {
panel.setString(someString);
}
}
});
JPanel bottomPanel = new JPanel();
bottomPanel.add(field);
bottomPanel.add(button);
JFrame frame = new JFrame();
frame.add(panel);
frame.add(bottomPanel, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public class DrawingPanel extends JPanel {
private String someString = "Stackoverflow";
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString(someString, 75, 75);
}
#Override
public Dimension getPreferredSize() {
return new Dimension (300, 100);
}
public void setString(String someString) {
this.someString = someString;
repaint();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
new SimpleDrawing();
}
});
}
}
I am trying to make an applet run as a JFrame. The code I have below is simple but should work. It will run as an JApplet but when I go to RUN AS --> nothing appears.
import java.awt.*;
import java.applet.Applet;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class LifeCycle extends Applet
{
private static final long serialVersionUID = 1L;
String output = "test";
String event;
public void init()
{
gui(); //I am not certain if this needs to be there.
event = "\nInitializing...";
printOutput();
}
public void start()
{
event = "\nStarting...";
printOutput();
}
public void stop()
{
event = "\nStopping...";
printOutput();
}
public void destroy()
{
event = "\nDestroying...";
printOutput();
}
private void printOutput()
{
System.out.println(event);
output += event;
repaint();
}
private void gui() {
JFrame f = new JFrame("Not resizable");
JPanel d = new JPanel();
// LifeCycle a = new LifeCycle();
// a.init();//not working
d.setLayout(new BorderLayout());
d.add(new JButton("a"));
d.add(new JButton("b"));
d.setBackground(Color.RED);
//f.add(new LifeCycle());
f.add(d);
f.setSize(545,340);
f.setResizable(false);
f.setLocationRelativeTo(null);
f.setTitle("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//a.destroy();
}
public void paint(Graphics g)
{
System.out.println("Graphics Paint Method!");
g.drawString(output, 100, 100);
}
public static void main(String[] args) {
LifeCycle l = new LifeCycle();
l.gui();
}
}
I would like to see the code that should be changed, but I cannot seem to find why this will not work. I have added to buttons to the panel to be displayed.
Don't mix AWT (Applet) with Swing components. Stick with just Swing.
Gear your class towards creating JPanels. Then you can place it in a JApplet if you want an applet or a JFrame if you want a JFrame.
Read up on use of BorderLayout -- you're adding multiple components to the default BorderLayout.CENTER position, and only one component, the last one added, will show.
For example ...
LifeCycle2.java
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;
class LifeCycle2 {
private static final int GAP = 5;
private static final int PREF_W = 545;
private static final int PREF_H = 340;
private JPanel mainPanel = new JPanel() {
#Override
public Dimension getPreferredSize() {
return LifeCycle2.this.getPreferredSize();
}
};
public LifeCycle2() {
JPanel buttonPanel = new JPanel(new GridLayout(1, 0, GAP, 0));
buttonPanel.add(new JButton("A"));
buttonPanel.add(new JButton("B"));
buttonPanel.setOpaque(false);
JPanel flowLayoutPanel = new JPanel();
flowLayoutPanel.setOpaque(false);
flowLayoutPanel.add(buttonPanel);
mainPanel.setLayout(new BorderLayout());
mainPanel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
mainPanel.setBackground(Color.red);
mainPanel.add(flowLayoutPanel, BorderLayout.NORTH);
}
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
public JComponent getMainPanel() {
return mainPanel;
}
}
Show as a JFrame,
LifeCycleFrame.java
import javax.swing.*;
public class LifeCycleFrame {
private static void createAndShowGui() {
LifeCycle2 lifeCycle2 = new LifeCycle2();
JFrame frame = new JFrame("LifeCycleTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(lifeCycle2.getMainPanel());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Show as an applet,
LifeCycleApplet.java
import java.lang.reflect.InvocationTargetException;
import javax.swing.JApplet;
import javax.swing.SwingUtilities;
public class LifeCycleApplet extends JApplet {
#Override
public void init() {
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
LifeCycle2 lifeCycle2 = new LifeCycle2();
getContentPane().add(lifeCycle2.getMainPanel());
}
});
} catch (InvocationTargetException | InterruptedException e) {
e.printStackTrace();
}
}
}
Add f.setVisible(true); to the end of the gui() method. Without this call your frame won't be shown.
Please read the "How to Make Frames" Tutorial