Coding is here.
I can't create any rectangle or circle inside frame.
the object of this project is to create converting celcius 2 Farenheit & Farenheit 2 Celcius.
so what I want is, please teach me to how to draw rectangle or oval in side the frame.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Frame;
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.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class C2F extends JComponent{
private double input1, output1;
private double input2, output2;
JPanel center = new JPanel();
JPanel top = new JPanel();
JPanel east = new JPanel();
JPanel south = new JPanel();
//for giving input & output
C2F(){
JFrame frame = new JFrame();
frame.setTitle("C2F");
frame.setSize(700,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.getContentPane().add(top,BorderLayout.NORTH);
frame.getContentPane().add(center,BorderLayout.CENTER);
frame.getContentPane().add(south,BorderLayout.SOUTH);
frame.getContentPane().add(east,BorderLayout.EAST);
frame.setVisible(true);
CC2F();
}
public void CC2F(){
//making frame
//give specific location
JLabel L1 = new JLabel("Please input Celcius or Fahrenheit to Convert");
top.add(L1);
JLabel l1 = new JLabel("Cel -> Fah");
south.add(l1);
JTextField T1 = new JTextField(12);
south.add(T1);
JButton B1 = new JButton("Convert");
south.add(B1);
JLabel l2 = new JLabel("Fah -> Cel");
south.add(l2);
JTextField T2 = new JTextField(12);
south.add(T2);
JButton B2 = new JButton("Convert");
south.add(B2);
//to create buttons and labels to give an answer
B1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
input1 = Double.parseDouble(T1.getText());
output1 = input1 *(9/5) + 32;
T2.setText(""+output1);
repaint();
}
});
B2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
input2 = Double.parseDouble(T2.getText());
output2 = (input2 - 32)/9*5;
T1.setText(""+output2);
}
});
//making events
//placing the buttons and labels
output1 = 0;
output2 = 0;
//initialize the value
}
public void paintComponent(Graphics g) {
//error spots. it compiles well. But this is not what I want.
super.paintComponent(g);
Graphics2D gg = (Graphics2D) g;
gg.setColor(Color.BLACK);
gg.drawOval(350, 500,12,12);
gg.setColor(Color.RED);
gg.fillRect(350, 500, 10,(int) output1);
gg.fillOval(350, 500, 10, 10);
gg.setColor(Color.RED);
gg.fillRect(350, 500, 10,(int) output2);
gg.fillOval(350, 500, 10, 10);
//to draw stuffs
}
public static void main(String[] args)
{//to run the program
new C2F();
}
}
You never actually add C2F to anything that would be able to paint it, therefore your paint method will never be called.
You should override paintComponent instead of paint, as you've broken the paint chain for the component which could cause no end of issues with wonderful and interesting paint glitches. Convention would also suggest that you should call super.paintComponent (when overriding paintComponent) as well before you perform any custom painting
See Painting in AWT and Swing and Performing Custom Painting for more details
As a general piece of advice, I'd discourage you from creating a frame within the constructor of another component, this will make the component pretty much unusable again (if you wanted to re-use it on another container for example)
import java.awt.BorderLayout;
import java.awt.Color;
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.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class C2F extends JComponent {
public C2F() {
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");
TestPane center = new TestPane();
JPanel top = new JPanel();
JPanel east = new JPanel();
JPanel south = new JPanel();
//give specific location
JLabel L1 = new JLabel("Please input Celcius or Fahrenheit to Convert");
top.add(L1);
JLabel l1 = new JLabel("Cel -> Fah");
south.add(l1);
JTextField T1 = new JTextField(12);
south.add(T1);
JButton B1 = new JButton("Convert");
south.add(B1);
JLabel l2 = new JLabel("Fah -> Cel");
south.add(l2);
JTextField T2 = new JTextField(12);
south.add(T2);
JButton B2 = new JButton("Convert");
south.add(B2);
//to create buttons and labels to give an answer
B1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
double input1 = Double.parseDouble(T1.getText());
double output1 = input1 * (9 / 5) + 32;
T2.setText("" + output1);
center.setOutput1(output1);
}
});
B2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
double input2 = Double.parseDouble(T2.getText());
double output2 = (input2 - 32) / 9 * 5;
T1.setText("" + output2);
center.setOutput2(output2);
}
});
//making events
frame.getContentPane().add(top, BorderLayout.NORTH);
frame.getContentPane().add(center, BorderLayout.CENTER);
frame.getContentPane().add(south, BorderLayout.SOUTH);
frame.getContentPane().add(east, BorderLayout.EAST);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private double output1, output2;
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 600);
}
public void setOutput1(double output1) {
this.output1 = output1;
repaint();
}
public void setOutput2(double output2) {
this.output2 = output2;
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLACK);
g2d.drawOval(350, 500, 12, 12);
g2d.setColor(Color.RED);
g2d.fillRect(350, 0, 10, (int) output1);
g2d.fillOval(350, 0, 10, 10);
g2d.setColor(Color.BLUE);
g2d.fillRect(350, 0, 10, (int) output2);
g2d.fillOval(350, 0, 10, 10);
g2d.dispose();
}
}
public static void main(String[] args) {//to run the program
new C2F();
}
}
Related
My JFrame uses a BorderLayout and it has a JLabel nested in several panels with different layout managers. I've tried several methods, however, cannot get the true position of where it sits in the frame.
I made a test UI and it seems like when other components are added the getX and getY parameters do not update. Other methods like getLocation do not provide a correct result either. Is there any way to obtain the exact location without manually calculating every possible offset from each component.
I am tracking the stated positions of the label (content) using a similar sized panel called content2 in the glass pane which I want to sit underneath content perfectly.
public class test {
private Dimension pSize = new Dimension(100,100);
private JFrame frame = new JFrame();
public static void main(String[] args) {
new test();
}
public test() {
//setup frame basics
frame.setPreferredSize(new Dimension(500,500));
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// setup GUI
JMenuBar j = new JMenuBar();
JMenuItem a = new JMenuItem("lol");
j.add(a);
JPanel j2 = new JPanel();
//setup main panel
JPanel main = new JPanel();
main.setBackground(Color.DARK_GRAY);
//setup side panel
FlowLayout f1 = new FlowLayout(FlowLayout.LEADING);
f1.setHgap(10);
f1.setVgap(0);
JPanel side = new JPanel();
side.setLayout(new BorderLayout());
side.setBackground(Color.gray);
side.setPreferredSize(new Dimension(150,100));
//setup JLabel (the main focus)
JLabel content = new JLabel("a");
content.setOpaque(true);
content.setBackground(Color.blue);
content.setPreferredSize(pSize);
// Setup the internal panels of side
JPanel top = new JPanel();//The panel where CONTENT is, the main focus
JPanel bot = new JPanel();
top.setBackground(Color.WHITE);
bot.setBackground(Color.orange);
top.setLayout(f1);
top.add(content);
side.add(top, BorderLayout.NORTH);
side.add(bot, BorderLayout.CENTER);
frame.add(main, BorderLayout.CENTER);
frame.add(side, BorderLayout.WEST);
frame.add(j2, BorderLayout.NORTH);
frame.setJMenuBar(j);
frame.pack();
frame.setVisible(true);
//Setting up the glass panel
JPanel pane = new JPanel();
pane.setLayout(null);
pane.setOpaque(false);
JPanel content2 = new JPanel();
content2.setBackground(Color.red);
content.revalidate();
int x = content.getX();
int y = content.getY();
// y = (int) content.getLocation().getY(); //returns a completely wrong location
//y = (int) content.getLocationOnScreen(); //returns a completely wrong location
/*
Point p = new Point();
p.setLocation(x, y);
p = SwingUtilities.convertPoint(content2, x, y, frame);
//SwingUtilities.convertPoint(content, p, frame);
y = (int) p.getY();
*
* Tried multiple SwingUtility converions to no avail
*
*/
// y = y +j.getHeight() + j2.getHeight(); // Manually calculating the Y off set works successfully but is too tedious for large project
y = y + content.getHeight();
content2.setBounds(x,y,100,100);
pane.add(content2);
frame.setGlassPane(pane);
frame.getGlassPane().setVisible(true);
frame.pack();
}
}
//frame.getContentPane().add(content);
//frame.add(content);
frame.setPreferredSize(new Dimension(500,500));
content.setBorder(BorderFactory.createEmptyBorder());
side.setLayout(new BorderLayout());
JPanel top = new JPanel();
JPanel bot = new JPanel();
top.setBackground(Color.WHITE);
bot.setBackground(Color.orange);
side.add(top, BorderLayout.NORTH);
top.setLayout(f1);
top.add(content);
side.add(bot, BorderLayout.CENTER);
frame.add(main, BorderLayout.CENTER);
frame.add(j2, BorderLayout.NORTH);
frame.add(side, BorderLayout.WEST);
frame.pack();
frame.setVisible(true);
JPanel pane = new JPanel();
pane.setLayout(null);
pane.setOpaque(false);
JPanel content2 = new JPanel();
content2.setBackground(Color.red);
content.revalidate();
int x = content.getX();
int y = content.getY();
// y = y +j.getHeight() + j2.getHeight();
y = y + content.getHeight();
content2.setBounds(x,y,100,100);
pane.add(content2);
frame.setGlassPane(pane);
frame.getGlassPane().setVisible(true);
frame.pack();
}
}
Conceptually you could make use of SwingUtilities.convertPoint or SwingUtilities.convertRectangle to convert between container contexts, for example...
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
GlassPane glassPane = new GlassPane();
JFrame frame = new JFrame();
frame.setGlassPane(glassPane);
frame.add(new MainPane(glassPane));
glassPane.setVisible(true);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface Tracker {
public void addTrackable(Trackable trackable);
public void removeTrackable(Trackable trackable);
}
public interface Trackable {
public JComponent[] getTrackedComponents();
}
public class MainPane extends JPanel {
private JLabel label = new JLabel("Catch me if you can");
public MainPane(Tracker tracker) {
setLayout(new GridBagLayout());
setBorder(new EmptyBorder(32, 32, 32, 32));
add(label);
tracker.addTrackable(new Trackable() {
#Override
public JComponent[] getTrackedComponents() {
return new JComponent[] { label };
}
});
}
}
public class GlassPane extends JPanel implements Tracker {
private List<Trackable> trackables = new ArrayList<>(8);
public GlassPane() {
setOpaque(false);
}
#Override
public void addTrackable(Trackable trackable) {
trackables.add(trackable);
revalidate();
repaint();
}
#Override
public void removeTrackable(Trackable trackable) {
trackables.remove(trackable);
revalidate();
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
for (Trackable trackable : trackables) {
for (JComponent component : trackable.getTrackedComponents()) {
Rectangle relativeBounds = SwingUtilities.convertRectangle(component.getParent(), component.getBounds(), this);
g2d.draw(relativeBounds);
}
}
g2d.dispose();
}
}
}
Well, that's pretty boring, it's one component inside one container, let's trying something a little more complicated...
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
GlassPane glassPane = new GlassPane();
JFrame frame = new JFrame();
frame.setLayout(new GridLayout(2, 2, 8, 8));
frame.add(new MainPane(glassPane));
frame.add(new MainPane(glassPane));
frame.add(new MainPane(glassPane));
frame.add(new MainPane(glassPane));
frame.setGlassPane(glassPane);
glassPane.setVisible(true);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface Tracker {
public void addTrackable(Trackable trackable);
public void removeTrackable(Trackable trackable);
}
public interface Trackable {
public JComponent[] getTrackedComponents();
}
public class MainPane extends JPanel {
private JLabel label = new JLabel("Catch me if you can");
public MainPane(Tracker tracker) {
setLayout(new GridBagLayout());
setBorder(new CompoundBorder(new LineBorder(Color.DARK_GRAY, 1, true), new EmptyBorder(32, 32, 32, 32)));
add(label);
tracker.addTrackable(new Trackable() {
#Override
public JComponent[] getTrackedComponents() {
return new JComponent[]{label};
}
});
}
}
public class GlassPane extends JPanel implements Tracker {
private List<Trackable> trackables = new ArrayList<>(8);
private List<Color> masterColors = new ArrayList<>(Arrays.asList(new Color[]{
Color.RED,
Color.GREEN,
Color.BLUE,
Color.CYAN,
Color.DARK_GRAY,
Color.GRAY,
Color.MAGENTA,
Color.ORANGE,
Color.PINK,
Color.YELLOW,}));
public GlassPane() {
setOpaque(false);
}
#Override
public void addTrackable(Trackable trackable) {
trackables.add(trackable);
revalidate();
repaint();
}
#Override
public void removeTrackable(Trackable trackable) {
trackables.remove(trackable);
revalidate();
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
List<Color> colors = new ArrayList<>(masterColors);
for (Trackable trackable : trackables) {
for (JComponent component : trackable.getTrackedComponents()) {
if (colors.isEmpty()) {
colors = new ArrayList<>(masterColors);
}
g2d.setColor(colors.remove(0));
Rectangle relativeBounds = SwingUtilities.convertRectangle(component.getParent(), component.getBounds(), this);
g2d.draw(relativeBounds);
}
}
g2d.dispose();
}
}
}
Here is a new smipler example program, trying to keep as close to your code as possible, that uses the convertRectangle but I can't manage to run it correctly
int y = (int) (r.getY() + r.getHeight()); ... are you deliberately trying to offset the "overlay"? This seems weird to me.
Another issue is, how does the GlassPane know when the child has changed position/size
So, I modified your code, getting rid of the "modification" to the x/y position (so I'm 100% sure that the conversion between context spaces is correct) and added a ComponentListener to monitor changes to the "target" component
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
public class Main {
private Dimension pSize = new Dimension(100, 100);
private JFrame frame = new JFrame();
private JLabel content = new JLabel("Grief");
private JPanel content2 = new JPanel();
private SidePane sidePane = new SidePane();
private GlassPane glass = new GlassPane();
private Menu menu = new Menu();
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
content.setBackground(Color.green);
content.setPreferredSize(pSize);
content.setOpaque(true);
//setup frame basics
frame.setPreferredSize(new Dimension(500, 500));
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setGlassPane(glass);
frame.add(new MainPane());
// glass.setNewLocation();
// glass.revalidate();
frame.getGlassPane().setVisible(true);
// glass.setNewLocation();
frame.pack();
frame.setVisible(true);
}
});
}
public class MainPane extends JPanel {
public MainPane() {
//this.setBackground(Color.orange);
this.setLayout(new BorderLayout());
this.add(sidePane, BorderLayout.WEST);
this.add(menu, BorderLayout.NORTH);
}
}
public class SidePane extends JPanel {
public SidePane() {
FlowLayout f1 = new FlowLayout(FlowLayout.LEADING);
this.setLayout(f1);
this.setBackground(Color.blue);
this.add(content);
}
}
public class Menu extends JPanel {
public Menu() {
this.setBackground(Color.orange);
}
}
public class GlassPane extends JPanel {
private Rectangle target;
public GlassPane() {
this.setOpaque(false);
setLayout(null);
content2.setBackground(Color.BLACK);
content2.setPreferredSize(pSize);
content2.setOpaque(true);
add(content2);
content.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
updateOverlay();
}
#Override
public void componentMoved(ComponentEvent e) {
updateOverlay();
}
});
}
protected void updateOverlay() {
// Rectangle t = new Rectangle();
// t.setBounds((int) content.getLocation().getX(), (int) content.getLocation().getY(), content.getWidth(), content.getHeight());
// Rectangle r = SwingUtilities.convertRectangle(content.getParent(), content.getBounds(), this);
// Rectangle r = SwingUtilities.convertRectangle(content.getParent(), content.getBounds(), this);
target = SwingUtilities.convertRectangle(content.getParent(), content.getBounds(), this);
content2.setBounds(target);
// r = SwingUtilities.convertRectangle(content.getParent(), t, this);
// int x = (int) r.getBounds().getX();
// x = (int) r.getX();
// int y = (int) (r.getY() + r.getHeight());
//
// content2.setBounds(x, y, 100, 100);
// this.add(content2);
}
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g.create();
if (target != null) {
g2d.setColor(Color.RED);
g2d.draw(target);
}
g2d.dispose();
}
}
}
If you have the coordinate within the component, transfer it to screen coordinates using your component's convertPointToScreen(). Afterwards you can transfer back to see where in the window it sits by using the frame's convertPointFromScreen().
Or eliminate one of the two steps by directly using convertPoint().
Fixed the positioning issue using #MadProgrammer 's method of SwingUtilities.convertRectangle and called a new method at the end of the constructor which positioned the tracker panel.
Created a separate class for the glass pane
private class GlassPane extends JPanel {
public GlassPane() {
this.setLayout(null);
}
public void setNewLocation() {
Rectangle r = SwingUtilities.convertRectangle(top, content.getBounds(), this);
JPanel content2 = new JPanel();
int x = (int) r.getBounds().getX();
x = (int) r.getX();
int y = (int) (r.getY() + r.getHeight() + 1);
content2.setBounds(x, y, 100,100);
this.add(content2);
}
}
And added a call to the new method setNewLocation() at the end of the constructor
public test() {
**...**
frame.pack();
frame.setVisible(true);
glass.setNewLocation();
}
In the main class Practice extends JFrame, there are three classes UpperPanel, CenterPanel and LowerPanel that extend JPanel.
I'm going to put buttons on UpperPanel and LowerPanel, and put a image on CenterPanel, and print it in one frame.
However, when the image prints out, three Panels aren't printed. and when three Panels print out, the image isn't printed.
I think the problem is setContentPane(new ImagePanel()); when I enter this code (in CenterPanel), Only images are printed. The rest of the panels(Upper, Center, Lower) are not output.
(I have created a separate image output class(ImagePanel extends JPanel), but It's okay to delete this class. But I want to use paintComponent(Graphics g).
I'm sorry for my poor English, and Thank you for reading it
please help me
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
public class Practice extends JFrame {
public int width = 480;
public int height = 720;
public Practice() {
setTitle("20201209");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(null);
setSize(width,height);
c.add(new UpperPanel());
c.add(new CenterPanel());
c.add(new LowerPanel());
setVisible(true);
}
class UpperPanel extends JPanel {
public UpperPanel() {
JPanel UpperPanel = new JPanel();
UpperPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 25));
UpperPanel.setBackground(Color.MAGENTA);
UpperPanel.setBounds(0, 0, 480, 100);
getContentPane().add(UpperPanel);
JButton btnEnlarge = new JButton("1");
btnEnlarge.setFont(new Font("궁서체", Font.PLAIN, 20));
btnEnlarge.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
UpperPanel.add(btnEnlarge);
JButton btnReduce = new JButton("2");
btnReduce.setFont(new Font("바탕체", Font.ITALIC, 20));
btnReduce.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
UpperPanel.add(btnReduce);
JButton btnFit = new JButton("3");
btnFit.setFont(new Font("돋움체", Font.BOLD, 20));
btnFit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
UpperPanel.add(btnFit);
}
}
class CenterPanel extends JPanel{
public CenterPanel() {
JPanel CenterPanel = new JPanel();
CenterPanel.setLayout(null);
CenterPanel.setBackground(Color.YELLOW);
CenterPanel.setBounds(0, 100, 480, 500);
CenterPanel.setOpaque(true);
getContentPane().add(CenterPanel);
setContentPane(new ImagePanel()); // when I enter this code, Only images are printed. The rest of the panels(Upper, Center, Lower) are not output
}
}
class ImagePanel extends JPanel { //this class is for image printing on CenterPanel
private ImageIcon icon = new ImageIcon("images/1771211.jpg");
private Image img = icon.getImage();
public void paintComponent(Graphics g) { //I want to use this code
super.paintComponent(g);
g.drawImage(img, 10, 110, this);
}
}
class LowerPanel extends JPanel {
public LowerPanel() {
JPanel LowerPanel = new JPanel();
LowerPanel.setLayout(null);
LowerPanel.setBackground(Color.BLACK);
LowerPanel.setBounds(0, 600, 480, 120);
getContentPane().add(LowerPanel);
getContentPane().add(new MyButton());
}
}
class MyButton extends JLabel{ //this class is for a Button on LowerPanel
MyButton(){
JButton btn = new JButton("4");
btn.setBounds(10, 610, 460, 100);
btn.setHorizontalAlignment(SwingConstants.CENTER);
btn.setVerticalAlignment(SwingConstants.CENTER);
btn.setFont(new Font("돋움체", Font.BOLD, 50));
btn.setBackground(Color.WHITE);
btn.setForeground(Color.RED);
btn.setOpaque(true);
getContentPane().add(btn);
}
}
public static void main(String[] args) {
new Practice();
}
}
Don't extend JFrame class unnecessarily
Don't use a null/AbsoluteLayout rather use an appropriate LayoutManager
Don't call setBounds() or setSize() on components, if you use a correct layout manager this will be handled for you
Call JFrame#pack() before setting the frame to visible
All Swing components should be called on the EDT via SwingUtilities.invokeLater
Here is a small example of what you want to achieve
TestApp.java:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestApp {
BufferedImage image;
public TestApp() {
createAndShowGui();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(TestApp::new);
}
private void createAndShowGui() {
JFrame frame = new JFrame("TestApp");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// load image
try {
image = ImageIO.read(new URL("https://i.stack.imgur.com/XNO5e.png"));
} catch (MalformedURLException ex) {
Logger.getLogger(TestApp.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(TestApp.class.getName()).log(Level.SEVERE, null, ex);
}
// upper panel
JPanel upperPanel = new JPanel(); // JPanels use FlowLayout by default
JButton button1 = new JButton("Button 1");
JButton button2 = new JButton("Button 2");
JButton button3 = new JButton("Button 3");
upperPanel.add(button1);
upperPanel.add(button2);
upperPanel.add(button3);
// center panel
JPanel centerPanel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(image.getWidth(), image.getHeight());
}
};
// lower panel
JPanel lowerPanel = new JPanel();
JButton button4 = new JButton("Button 4");
JButton button5 = new JButton("Button 5");
JButton button6 = new JButton("Button 6");
lowerPanel.add(button4);
lowerPanel.add(button5);
lowerPanel.add(button6);
frame.add(upperPanel, BorderLayout.NORTH); // JFrame uses BorderLayout by default
frame.add(centerPanel, BorderLayout.CENTER);
frame.add(lowerPanel, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
}
how to draw below a label / button? -JAVA
I wanted to write a coordinate calculation program for ax^2 + bx + c, but thats not the important point...
I'd like to draw the graph only via AWT and the paint method. (not implemented yet), but I'm not able to set the paint method in the foreground. Can you please help me to fix the problem so that the paint is at least visible?
I have attached a outline of my thoughts.
Sorry for my bad english
idea
import java.awt.Button;
import java.awt.Canvas;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextField;
public class MyWindow extends Frame {
Frame frame;
Label l1;
Label l2;
Label l3;
Button b1;
TextField t1;
TextField t2;
TextField t3;
Panel panel;
Canvas canvas;
MyWindow() {
frame = new Frame("GraphPlotter");
frame.setSize(800, 800);
frame.setLayout(new FlowLayout());
l1 = new Label("f(x)= ");
l2 = new Label(" x^2 + ");
l3 = new Label(" x + ");
t1 = new TextField("1");
t2 = new TextField("2");
t3 = new TextField("3");
b1 = new Button("Plot");
frame.add(l1);
frame.add(t1);
frame.add(l2);
frame.add(t2);
frame.add(l3);
frame.add(t3);
frame.add(b1);
frame.setVisible(true);
}
public void paint(Graphics g) {
g.fillRect(10, 10, 300, 300); // ist im "Hintergrund"??
}
}
` public class Start {
public static void main(String[] args) {
MyWindow window = new MyWindow();
}
}
`
You haven't set a color before
g.fillRect(10, 10, 300, 300);
I solved that problem like two months or so, but I'm a bit motivated at the moment, so I am going to answer my question on my own. Info: repaint() calls paint, so you don't have to implement this method on your own.
in the task I forgot to:
-generate a canvas
-use layout manager
-call paint with the methods repaint(); or update();
The question was only how to paint and this should be clear after reading following code:
package delete;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextField;
public class AwtFrame extends Frame {
AwtCanvas c;
Panel p1;
Label la_ax2, la_bx, la_c;
TextField tf_Ax2, tf_bx, tf_c;
public AwtFrame() {
super("paint example.");
this.setSize(800, 800);
initComp();
addComp();
// TODO: write a graph drawing method
c.repaint(); // paints a line of your graph
this.setVisible(true);
}
public void initComp() {
p1 = new Panel();
la_ax2 = new Label("x^2 ");
la_bx = new Label("+ x ");
la_c = new Label("+ c ");
tf_Ax2 = new TextField(0);
tf_bx = new TextField(0);
tf_c = new TextField(0);
c = new AwtCanvas();
}
public void addComp() {
this.setLayout(new BorderLayout());
p1.setLayout(new FlowLayout());
this.add(p1, BorderLayout.NORTH);
this.add(c, BorderLayout.CENTER);
p1.add(tf_Ax2);
p1.add(la_ax2);
p1.add(tf_bx);
p1.add(la_bx);
p1.add(tf_c);
p1.add(la_c);
}
public static void main(String[] args) {
new AwtFrame();
}
}
package delete;
import java.awt.Canvas;
import java.awt.Graphics;
import java.util.LinkedList;
public class AwtCanvas extends Canvas {
// LinkedList<ToImplement> coords = new LinkedList<ToImplement>();
// TODO: implement plotter
public void paint(Graphics g) {
g.drawLine(40, 40, 100, 100);
g.drawLine(54, 22, 300, 200);
}
}
The intention of my code is to create a rectangle when the button is clicked. The button works fine but the rectangle itself is not showing up on the screen, and there are no errors. Thank you for helping btw.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Tester {
static JButton button;
static JFrame frame;
static JPanel panel;
static Rectangle rec;
static void init(){
button = new JButton();
frame = new JFrame();
panel = new JPanel();
rec = new Rectangle(30,30,30,30);
button.setVisible(true);
panel.add(button);
frame.add(panel);
frame.setVisible(true);
panel.setVisible(true);
frame.setSize(200, 200);
button.setBackground(Color.GREEN);
button.setBounds(30, 30, 20, 20);
}
public static void main(String[] args) {
init();
ActionListener listener = new RectangleMover();
button.addActionListener(listener);
}
static class RectangleMover implements ActionListener{
#Override
public void actionPerformed(ActionEvent arg0) {
RectanglePainter r = new RectanglePainter();
r.add(rec);
}
}
static class RectanglePainter extends JPanel{
void add(Rectangle r){
rec = r;
repaint();
}
protected void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
Random r = new Random();
int i =r.nextInt(2);
if (i==1)
g2.setColor(Color.BLUE);
else
g2.setColor(Color.RED);
g2.fill(rec);
g2.draw(rec);
}
}
}
Your generally approach is slightly skewed, rather than using another JComponent to "act" as the shape, you should be using it to paint all the shapes through it's paintComponent method
From my "red rectangle" period...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Tester {
public static void main(String[] args) {
new Tester();
}
public Tester() {
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 {
private JPanel panel;
private JButton button;
private JLabel label;
private ShapePane shapePane;
public TestPane() {
setLayout(new BorderLayout());
button = new JButton("Rectangle");
panel = new JPanel();
label = new JLabel();
button.setVisible(true);
panel.add(button);
panel.add(label);
shapePane = new ShapePane();
add(shapePane);
add(panel, BorderLayout.SOUTH);
class ClickListener implements ActionListener {
private int X = 20;
private int Y = 20;
#Override
public void actionPerformed(ActionEvent arg0) {
int width = shapePane.getWidth();
int height = shapePane.getHeight();
int x = (int)(Math.random() * (width - 20)) + 10;
int y = (int)(Math.random() * (height - 20)) + 10;
int w = (int)(Math.random() * (width - x));
int h = (int)(Math.random() * (height - y));
shapePane.add(new Rectangle(x, y, w, h));
}
}
ActionListener listener = new ClickListener();
button.addActionListener(listener);
}
}
public class ShapePane extends JPanel {
private List<Shape> shapes;
public ShapePane() {
shapes = new ArrayList<>(25);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
public void add(Rectangle rectangle) {
shapes.add(rectangle);
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.RED);
for (Shape shape : shapes) {
g2.draw(shape);
}
}
}
}
As to answer your basic question, you could have tried calling revalidate and repaint, but because of the BorderLayout I doubt it would have worked as you would have basically been trying to replace the panel with your ShapeChanger component, and there are better ways to do that
Can someone please assist me on why my background color of the frame is not being set. Is it possible to set the background color within the Paint() or must it be done in the JColor constructor
I am supposed to do the following for the BG color-
Write A GUI application that displays a single JButton and any background color you choose.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
/**
*
* #author Curtis
*/
public class JColor extends JFrame implements ActionListener
{
Font myFont = new Font("Playbill", Font.PLAIN, 28);
JButton myButton = new JButton("Click Me!");
Color bgColor = new Color(255, 97, 3);
Color txtColor = new Color(0, 0, 205);
String firstName = "Curtis";
String lastName = "Sizemore";
public JColor()
{
super("String Painting Fun");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout (new BorderLayout());
add(myButton, BorderLayout.SOUTH);
setDefaultLookAndFeelDecorated(true);
setBackground(Color.BLUE);
}
#Override
public void paint(Graphics e)
{
super.paint(e);
}
public static void main(String[] args)
{
final int TALL = 200;
final int WIDE = 250;
JColor frame = new JColor();
frame.setSize(WIDE, TALL);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e)
{
throw new UnsupportedOperationException("Not supported yet.");
}
}
Try calling it on the ContentPane instance (more info here)
public JColor() {
super("String Painting Fun");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
add(myButton, BorderLayout.SOUTH);
setDefaultLookAndFeelDecorated(true);
getContentPane().setBackground(Color.BLUE);//<- update
}