JTabbedPanel and Paint - java

I have small issue. In main i have such thing:
JTabbedPane tabsPane = new JTabbedPane();
add(tabsPane,BorderLayout.CENTER);
JPanel tab1Panel = new JPanel();
JPanel tab2Panel = new JPanel();
//DrawingWindow drawingWindow= new DrawingWindow();
//add(drawingWindow);
tabsPane.addTab("Animacja", tab1Panel);
tabsPane.addTab("Wykresy", tab2Panel);
JButton test = new JButton("Press");
tab2Panel.add(test);
Drawing Window class
public class DrawingWindow extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
public static Balls balls=new Balls();
public DrawingWindow() {
MakeBall();
}
private void MakeBall()
{
balls=new Balls(10,205,5,10);
}
public void paint(Graphics gg){
super.paint(gg);
Graphics2D g = (Graphics2D) gg;
g.setColor(Color.GRAY);
g.fillRect(0,70,515,410);
g.setColor(Color.WHITE);
g.drawLine(10, 285, 57, 265);
g.drawLine(10, 285, 57, 305);
g.drawLine(515, 285, 458, 265);
g.drawLine(515, 285, 458, 305);
for(int ii=0;ii<Parameters.numberOfCovers;ii++)
{
if(Parameters.whatCovers[ii]==0)
{
g.setColor(Color.YELLOW);
g.fillRect(132+(57*2*ii), 205, 29+2*Parameters.cmCovers[ii], 150 );
}
if(Parameters.whatCovers[ii]==1)
{
g.setColor(Color.GREEN);
g.fillRect(132+(57*2*ii), 205, 29+2*Parameters.cmCovers[ii], 150 );
}
// Ellipse2D.Double shape = new Ellipse2D.Double(balls.getX(), balls.getY(), balls.getVelocity(),balls.getRadius());
// g.fill(shape);
repaint();
}
}
public void funkcja()
{
repaint();
}
}
And my question is after uncommenting the // in Main my JTabbedPanel disappears.
I want paint to draw in JTab.
http://forum.4programmers.net/Java/232952-jtabbedpanel_i_paint?mode=download&id=6326 <-- While it is commented
http://forum.4programmers.net/Java/232952-jtabbedpanel_i_paint?mode=download&id=6327 <-- After uncommenting.
Iam kinda newbie in Java so I would like to get easy answers :P.

Hej,
replace this
JPanel tab1Panel = new JPanel();
with that
JPanel tab1Panel = new DrawingWindow();
up to now, you add the DrawingPanel to another JPanel, but if you want to draw on your Tab, then add create a JPanel, which you'll add to your JTabbedPane with addTab().

Related

Issue when adding two JPanels

I'm trying to add two JPanels to a JFrame, one with a simple backround and another one with buttons etc. Either I get only buttons or only the background. I can't find a solution to my problem anywhere, so any help would be appreciated. I'm still new to Java, so please don't hate.
GuiMainMenu:
public class GuiMainMenu extends JFrame implements ActionListener, KeyListener {
private static final long serialVersionUID = -7936366600070922227L;
Color blue = new Color(114, 137, 218);
Color gray = new Color(44, 47, 51);
Color white = new Color(255, 255, 255);
ImagePanel panel = new ImagePanel(new ImageIcon("image.png").getImage());
public static int width;
public static int height;
JPanel p = new JPanel();
JPanel p1 = new JPanel();
JLabel l = new JLabel();
JLabel l1 = new JLabel();
JLabel l2 = new JLabel();
JButton b = new JButton();
JButton b1 = new JButton();
JButton b2 = new JButton();
String title = "-";
public GuiMainMenu() {
setSize(m.X, m.Y);
setTitle(title);
setResizable(true);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addKeyListener(this);
p.setLayout(null);
width = getWidth();
height = getHeight();
getRootPane().addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
width = getWidth();
height = getHeight();
addButtons();
addLabels();
}
});
addLabels();
addButtons();
add(p);
add(panel);
setVisible(true);
}
public void addLabels() {
l.setSize(width, height);
l.setLocation(5, -40);
l.setText("x");
l.setHorizontalAlignment(SwingConstants.LEFT);
l.setVerticalAlignment(SwingConstants.BOTTOM);
l.setForeground(blue);
l.setFont(new Font("Trebuchet MS", Font.PLAIN, 15));
l1.setSize(width, height);
l1.setLocation(-22, -40);
l1.setText("y");
l1.setHorizontalAlignment(SwingConstants.RIGHT);
l1.setVerticalAlignment(SwingConstants.BOTTOM);
l1.setForeground(blue);
l1.setFont(new Font("Trebuchet MS", Font.PLAIN, 15));
l2.setText("test label");
l2.setSize(width, height);
l2.setLocation(0, -75);
l2.setVerticalAlignment(SwingConstants.CENTER);
l2.setHorizontalAlignment(SwingConstants.CENTER);
l2.setForeground(blue);
l2.setFont(new Font("Trebuchet MS", Font.BOLD, 26));
p.add(l);
p.add(l1);
p.add(l2);
validate();
}
public void addButtons() {
b.setText("button0");
b.setFocusable(false);
b.setBorder(null);
b.setLocation(width / 2 - 200, height / 2 - 35);
b.setSize(400, 35);
b.setForeground(white);
b.setBackground(blue);
b.addActionListener(this);
b1.setText("button1");
b1.setFocusable(false);
b1.setBorder(null);
b1.setLocation(width / 2 - 200, height / 2 + 10);
b1.setSize(400, 35);
b1.setForeground(white);
b1.setBackground(blue);
b1.addActionListener(this);
p.add(b);
p.add(b1);
validate();
}
#Override
public void actionPerformed(ActionEvent arg0) {
}
#Override
public void keyPressed(KeyEvent arg0) {
}
#Override
public void keyReleased(KeyEvent arg0) {
}
#Override
public void keyTyped(KeyEvent arg0) {
}
}
ImagePanel Class:
class ImagePanel extends JPanel {
private static final long serialVersionUID = -7270956677693528549L;
private Image img;
public ImagePanel(String img) {
this(new ImageIcon(img).getImage());
}
public ImagePanel(Image img) {
this.img = img;
}
public void paintComponent(Graphics g) {
g.drawImage(img, 0, 0, GuiMainMenu.width, GuiMainMenu.height, null);
}
}
p.setLayout(null);
Don't use a null layout. Swing was designed to be used with layout managers.
Read the section from the Swing tutorial on Layout Managers for more information and working examples.
Either I get only buttons or only the background
add(p);
add(panel);
The default layout manager for a JFrame is the BorderLayout. If you don't specify a constraint both components get added to the CENTER. However only the last one added will be displayed.
Try the following to see the difference:
add(p, BorderLayout.PAGE_STRT);
add(panel, BorderLayout.CENTER);
one with a simple backround and another one with buttons etc.
However above is not what you want. Swing components have a parent/child relationship. So what you really need is:
backgroundPanel.add(buttonPanel);
add(backgroundPanel, BorderLayout.CENTER);
Note I used more meaningful names because "p" and "panel" and not descriptive. Use descriptive names for variable so people can understand what they mean.
I suppose you want to display a JFrame with a background image and various components. I think after reviewing your code that there is some misunderstanding on your part causing the problem.
I've created a short snippet of code that does the basics and maybe helps you to solve your problem. (Not tested!)
#SuppressWarnings("serial")
public class GuiMainMenu extends JFrame{
private BufferedImage imageBackground; // TODO: load your background image
public GuiMainMenu(){
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(1024, 768));
setMinimumSize(new Dimension(800, 600));
// TODO: setLayout if needed
JPanel panel = (JPanel)add(new JPanel(){
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(imageBackground, 0, 0, this);
}
});
addOtherComponents(panel);
pack();
setLocationRelativeTo(null);
setTitle("Your Title her");
setVisible(true);
}
private void addOtherComponents(JPanel panel){
//TODO: add the needed Stuff
//panel.add ...
}
}

JPanel and JFrame size not changing [duplicate]

This question already has answers here:
paintComponent not painting onto JPanel
(2 answers)
Closed 5 years ago.
I'm making a game in Java and first I didn't use a JPanel which caused flickering on repaint() and so I decided to use it. I'm not sure how to implement it in my current code. When I tried to do so all I got was a window that was as small as it gets. My original Window class code:
public class Window extends JFrame {
private double stepLen;
public Window(double stepLen) {
this.stepLen = stepLen;
this.setSize(800, 600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.setTitle("Frogger");
this.setLayout(null);
getContentPane().setBackground(Color.black);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
int x = (dim.width - this.getSize().width)/2;
int y = (dim.height - this.getSize().height)/2;
this.setLocation(x, y);
JLabel goal = new JLabel();
goal.setText("|=========|");
goal.setForeground(Color.WHITE);
goal.setFont(new Font("Seif", Font.PLAIN, 20));
add(goal);
goal.setBounds(325, -10, 600, 50);
setFocusable(true);
requestFocusInWindow();
this.setVisible(true);
}
This code works and it creates a window.
Main class:
Window window = new Window(50);
And then I tried to do it this way:
I have separate GameFrame (JFrame) and GameCanvas (JPanel) classes.
The Frame looks like this:
public class GameFrame extends JFrame{
private double stepLen;
public GameFrame() {
this.stepLen = 50;
this.setSize(800, 600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.setTitle("Frogger");
this.setLayout(null);
this.setVisible(true);
this.getContentPane().setBackground(Color.black);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
int x = (dim.width - this.getSize().width)/2;
int y = (dim.height - this.getSize().height)/2;
GameCanvas gcanvas = new GameCanvas();
this.add(gcanvas);
this.pack();
this.setLocation(x, y);
}
}
}
And the GameCanvas class
public class GameCanvas extends JPanel {
public GameCanvas() {
setDoubleBuffered(true);
JLabel goal = new JLabel();
goal.setText("|=========|");
goal.setForeground(Color.WHITE);
goal.setFont(new Font("Seif", Font.PLAIN, 20));
this.add(goal);
goal.setBounds(325, -10, 600, 50);
this.getPreferredSize();
this.setVisible(true);
this.repaint();
}
Camickr is correct - go up vote and mark his answer as correct, this is only here to save him from pulling out what little hair he has remaining
You're using a null layout, without taking over its responsibility
Failed to provide sizing hints to for the component to allow the layout manager (which you're no longer using) to do it's job
This are all common mistakes, to which there are countless answers already provided
GameFrame
public class GameFrame extends JFrame {
private double stepLen;
public GameFrame() {
this.stepLen = 50;
this.setSize(800, 600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.setTitle("Frogger");
// Well, there's your problem...
//this.setLayout(null);
// Don't do this here...
this.setVisible(true);
this.getContentPane().setBackground(Color.black);
// Simpler way to achieve this
//Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
//int x = (dim.width - this.getSize().width) / 2;
//int y = (dim.height - this.getSize().height) / 2;
GameCanvas gcanvas = new GameCanvas();
this.add(gcanvas);
this.pack();
//this.setLocation(x, y);
setLocationRelativeTo(null);
setVisible(true);
}
}
GameCanvas
public class GameCanvas extends JPanel {
public GameCanvas() {
// Pointless
//setDoubleBuffered(true);
JLabel goal = new JLabel();
goal.setText("|=========|");
goal.setForeground(Color.WHITE);
goal.setFont(new Font("Seif", Font.PLAIN, 20));
this.add(goal);
// Pointless
//goal.setBounds(325, -10, 600, 50);
// Pointless
//this.getPreferredSize();
// Pointless
//this.setVisible(true);
// Pointless
//this.repaint();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
public void paintComponent(Graphics g) {
int firstRoad = 5;
int i = 0;
int max = 10;
Graphics2D g2 = (Graphics2D) g;
super.paintComponent(g2);
g2.setColor(Color.WHITE);
g2.drawRect(5, 30, 75, 40);
while (i < max) {
g2.setColor(Color.WHITE);
g2.setStroke(new BasicStroke(3));
if (i % 2 == 0) {
g.setColor(Color.WHITE);
g.drawRect(3, firstRoad + 50 * i, 793, 50);
//g.fillRect(3, firstRoad + 50 * i, 793, 50);
} else {
g2.setColor(Color.WHITE);
g2.drawRect(3, firstRoad + 50 * i, 793, 50);
}
i++;
}
}
}
So, the way I was taught in my AP Computer Science class is to set your frame size and other frame characteristics in your main. Here is an example:
import javax.swing.JFrame;
public class theSetupClass{
public static void main(String[] args){
JFrame theGUI = new JFrame();
theGUI.setSize(300,400); //Sets the frame size to 300 by 400
theGUI.setTitle("Example");
theGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
theComponentClass component = new theComponentClass(); //Create new theComponentClass
frame.add(component);//Add theComponentClass to theGUI
frame.setVisible(true);
}
}
The code above creates the JFrame and adds the following class to it.
import java.awt.*;
import javax.swing.*;
public class theComponentClass extends JComponent{
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
Rectangle r = new Rectangle(10,10,this.getWidth()-10,this.getHeight()-10);
//Creates a rectangle that is 10 pixels away from all sides of the frame
g2.fill(r); //Draws and fills the rectangle
}
}
I hope that you find this helpful!

repaint does not seem to call paintComponent

I am trying to simulate a traffic light with radio buttons. No matter where I put the call to repaint(), it does not seem to call the paintComponent method. Any help would be appreciated. Here is my code. Sorry if this is kind of long.
package trafficlight;
import java.awt.BorderLayout;
import javax.swing.*;
import java.awt.event.*;
public class Frame extends JFrame{
Drawing ob = new Drawing();
private JPanel buttonPanel;
private JRadioButton red;
private JRadioButton yellow;
private JRadioButton green;
public Frame(String title, int width, int height) {
super(title);
setSize(width, height);
buttonPanel = new JPanel();
//creating JFrame components
red = new JRadioButton("Red");
yellow = new JRadioButton("Yellow");
green = new JRadioButton("Green");
buttonPanel.add(red);
buttonPanel.add(yellow);
buttonPanel.add(green);
//JRadioButton group allows only one button to be selected at a time
ButtonGroup group = new ButtonGroup();
group.add(red);
group.add(yellow);
group.add(green);
//adding components to frame
add(buttonPanel, BorderLayout.SOUTH);
//Adding action listeners
red.addActionListener(new Listener());
yellow.addActionListener(new Listener());
green.addActionListener(new Listener());
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
//Listener class to handle action events
private class Listener implements ActionListener{
#Override
public void actionPerformed(ActionEvent e){
if(red.isSelected()){
ob.setRed(true);
ob.setYellow(false);
ob.setGreen(false);
ob.repaint();
}
else if(yellow.isSelected()){
ob.setYellow(true);
ob.setGreen(false);
ob.setRed(false);
ob.repaint();
}
else if(green.isSelected()){
ob.setGreen(true);
ob.setYellow(false);
ob.setRed(false);
ob.repaint();
}
}
}
}
Here is my seconds class
package trafficlight;
import java.awt.*;
import javax.swing.*;
public class Drawing extends JPanel{
private boolean red = false;
private boolean yellow = false;
private boolean green = false;
public void setRed(boolean clicked){
this.red = clicked;
}
public void setYellow(boolean clicked){
this.yellow = clicked;
}
public void setGreen(boolean clicked){
this.green = clicked;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
g.drawRect(85, 20, 60, 110);
if(!red){
g.setColor(Color.black);
g.drawOval(100, 25, 30, 30);
}
else{
g.setColor(Color.red);
g.fillOval(100, 25, 30, 30);
}
if(!yellow){
g.setColor(Color.black);
g.drawOval(100, 60, 30, 30);
}
else{
g.setColor(Color.yellow);
g.fillOval(100, 60, 30, 30);
}
if(!green){
g.setColor(Color.black);
g.drawOval(100, 95, 30, 30);
}
else{
g.setColor(Color.green);
g.fillOval(100, 95, 30, 30);
}
}
}
And here's the main method
package trafficlight;
public class TrafficLight {
public static void main(String[] args) {
Frame test = new Frame("TrafficLight", 250, 250);
test.add(new Drawing());
}
}
Some improvements for your code
Don't inherit from JFrame. You don't add any value to this class (composition over inheritance)
Your ActionListener doesn't need to be a named class because it hasn't got any state
No need for a field in your case
Use the Color constants with the UPPERCASE i.e. Color.BLACK
Enqueue Swing application in the EDT
Use more descriptive names for classes and variables
Then your program may look like this:
public class TrafficLightUI {
public TrafficLightUI(String title, int width, int height) {
JFrame frame = new JFrame(title);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(width, height);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
JPanel mainPanel = new JPanel(new BorderLayout());
JPanel buttonPanel = new JPanel();
JRadioButton redRadioButton = new JRadioButton("Red");
JRadioButton yellowRadioButton = new JRadioButton("Yellow");
JRadioButton greenRadioButton = new JRadioButton("Green");
buttonPanel.add(redRadioButton);
buttonPanel.add(yellowRadioButton);
buttonPanel.add(greenRadioButton);
//JRadioButton group allows only one button to be selected at a time
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(redRadioButton);
buttonGroup.add(yellowRadioButton);
buttonGroup.add(greenRadioButton);
TrafficLightPanel trafficLight = new TrafficLightPanel();
//adding components to frame
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
mainPanel.add(trafficLight, BorderLayout.CENTER);
//Adding action listeners
redRadioButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setTrafficLight(true, false, false, trafficLight);
}
});
yellowRadioButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setTrafficLight(false, true, false, trafficLight);
}
});
greenRadioButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setTrafficLight(false, false, true, trafficLight);
}
});
frame.add(mainPanel);
frame.setVisible(true);
}
private void setTrafficLight(boolean red, boolean yellow, boolean green, TrafficLightPanel trafficLight) {
trafficLight.setGreen(green);
trafficLight.setYellow(yellow);
trafficLight.setRed(red);
trafficLight.repaint();
}
}
TrafficLightPanel
public class TrafficLightPanel extends JPanel {
private static final long serialVersionUID = 1L;
private boolean red = false;
private boolean yellow = false;
private boolean green = false;
public void setRed(boolean isRed) {
this.red = isRed;
}
public void setYellow(boolean isYellow) {
this.yellow = isYellow;
}
public void setGreen(boolean isGreen) {
this.green = isGreen;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.drawRect(85, 20, 60, 110);
if (!red) {
g.setColor(Color.BLACK);
g.drawOval(100, 25, 30, 30);
} else {
g.setColor(Color.RED);
g.fillOval(100, 25, 30, 30);
}
if (!yellow) {
g.setColor(Color.BLACK);
g.drawOval(100, 60, 30, 30);
} else {
g.setColor(Color.YELLOW);
g.fillOval(100, 60, 30, 30);
}
if (!green) {
g.setColor(Color.BLACK);
g.drawOval(100, 95, 30, 30);
} else {
g.setColor(Color.GREEN);
g.fillOval(100, 95, 30, 30);
}
}
}
Main
public class TrafficLight {
public static void main(String... args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TrafficLightUI("TrafficLight", 250, 250);
}
});
}
}

Resizing Graphics2D Objects with JFrame Resize

I am making a GUI that has Graphics2D objects drawn on a JPanel within a JFrame. When I resize the window the Graphics2D objects reduce into a tiny rectangle. How can I set the drawing to resize with the JFrame when the user resizes the window?
I have tried using gridlayout, flowlayout, borderlayout, and settled on gridbaglayout. This helps with the resizing of btnPanel and the JButton but not for the Graphics2D objects.
Here is my self contained example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class DrawPanelMain extends JPanel {
/*
* Variables used to set the value of preferred height and width
*/
public static final double version = 0.0;
JPanel btnPanel = new JPanel();
JPanel switchPanel = new JPanel();
DrawEllipses drawEllipses = new DrawEllipses(POINT_LIST);
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
initializePointList();
createAndShowGui();
}
});
}
public static java.util.List<Point> POINT_LIST = new ArrayList<>();
/*
* This loop will initialize POINT_LIST with the set of points for drawing the ellipses.
* The for each loop initializes points for the top row and the second for loop draws the
* right triangle.
*/
public static void initializePointList() {
int ellipsePointsYCoordinate[] = {140, 200, 260, 320, 380, 440, 500, 560, 620};
int ellipsePointsXCoordinate[] = {140, 200, 260, 320, 380, 440, 500, 560, 620, 680};
int xx = 80;
for (int aXt : ellipsePointsXCoordinate) {
POINT_LIST.add(new Point(aXt, xx));
}
for (int i = 0; i < ellipsePointsYCoordinate.length; i++) {
for (int j = i; j < ellipsePointsYCoordinate.length; j++) {
POINT_LIST.add(new Point(ellipsePointsXCoordinate[i], ellipsePointsYCoordinate[j]));
}
}
}
public DrawPanelMain() {
switchPanel.setBorder(BorderFactory.createLoweredSoftBevelBorder());
switchPanel.setBackground(Color.DARK_GRAY);
switchPanel.add(drawEllipses);
switchPanel.revalidate();
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
// first column
c.gridx = 0;
add(switchPanel, c);
// second column
c.gridx = 1;
add(switchPanel, c);
// first row
c.gridy = 0;
// second row
c. gridy = 1;
add(btnPanel, c);
btnPanel.add(new JButton(new AddSwitchAction("Add Switch Panel")));
}
public static void createAndShowGui() {
JFrame frame = new JFrame("RF Connection Panel " + version);
frame.setLayout(new BorderLayout());
frame.add(new DrawPanelMain());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(false);
//frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
/*
* AddSwitchAction will add a new pane to the tabbedPane when the add switch button is clicked
*/
private class AddSwitchAction extends AbstractAction {
public AddSwitchAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
String title = "Switch ";
DrawEllipses tabComponent = new DrawEllipses(POINT_LIST);
switchPanel.add(title, tabComponent);
}
}
}
#SuppressWarnings("serial")
class DrawEllipses extends JPanel {
private final int PREF_W = 750; //Window width
private final int PREF_H = 750; //Window height
private final int OVAL_WIDTH = 30;
private static final Color INACTIVE_COLOR = Color.RED;
private static final Color ACTIVE_COLOR = Color.green;
private java.util.List<Point> points;
private java.util.List<Ellipse2D> ellipses = new ArrayList<>();
private Map<Ellipse2D, Color> ellipseColorMap = new HashMap<>();
/*
* This method is used to populate "ellipses" with the initialized ellipse2D dimensions
*/
public DrawEllipses(java.util.List<Point> points) {
this.points = points;
for (Point p : points) {
int x = p.x - OVAL_WIDTH / 2;
int y = p.y - OVAL_WIDTH / 2;
int w = OVAL_WIDTH;
int h = OVAL_WIDTH;
Ellipse2D ellipse = new Ellipse2D.Double(x, y, w, h);
ellipses.add(ellipse);
ellipseColorMap.put(ellipse, INACTIVE_COLOR);
}
MyMouseAdapter mListener = new MyMouseAdapter();
addMouseListener(mListener);
addMouseMotionListener(mListener);
}
/*
* paintComponent is used to paint the ellipses
*/
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
for (Ellipse2D ellipse : ellipses) {
g2.setColor(ellipseColorMap.get(ellipse));
g2.fill(ellipse);
g2.setColor(Color.BLACK);
g2.setStroke(new BasicStroke(2));
g2.draw(ellipse);
}
/*
* Set the font characteristics, color, and draw the row labels.
*/
g.setFont(new Font("TimesRoman", Font.BOLD, 18));
g.setColor(Color.BLACK);
//Along the top row
g.drawString("External Port", 10, 50);
g.drawString("1", 135, 50);
g.drawString("2", 195, 50);
g.drawString("3", 255, 50);
g.drawString("4", 315, 50);
g.drawString("5", 375, 50);
g.drawString("6", 435, 50);
g.drawString("7", 495, 50);
g.drawString("8", 555, 50);
g.drawString("9", 615, 50);
g.drawString("10", 672, 50);
//Along the Y-axis
g.drawString("Radio 2", 40, 145);
g.drawString("3", 90, 205);
g.drawString("4", 90, 265);
g.drawString("5", 90, 325);
g.drawString("6", 90, 385);
g.drawString("7", 90, 445);
g.drawString("8", 90, 505);
g.drawString("9", 90, 565);
g.drawString("10", 90, 625);
//Along the X-Axis
g.drawString("1", 135, 670);
g.drawString("2", 195, 670);
g.drawString("3", 255, 670);
g.drawString("4", 315, 670);
g.drawString("5", 375, 670);
g.drawString("6", 435, 670);
g.drawString("7", 495, 670);
g.drawString("8", 555, 670);
g.drawString("9", 615, 670);
//Draws a 3DRect around the top row of ellipse2D objects
g2.setColor(Color.lightGray);
g2.draw3DRect(120, 60, 580, 40, true);
g2.draw3DRect(121, 61, 578, 38, true);
g2.draw3DRect(122, 62, 576, 36, true);
}
/*
* MouseAdapter is extended for mousePressed Event that detects if the x, y coordinates
* of a drawn ellipse are clicked. If the color is INACTIVE it is changed to ACTIVE and
* vice versa.
*/
private class MyMouseAdapter extends MouseAdapter {
#Override
/*
* When mousePressed event occurs, the color is toggled between ACTIVE and INACTIVE
*/
public void mousePressed(MouseEvent e) {
Color c;
for (Ellipse2D ellipse : ellipses) {
if (ellipse.contains(e.getPoint())) {
c = (ellipseColorMap.get(ellipse) == INACTIVE_COLOR) ? ACTIVE_COLOR : INACTIVE_COLOR;
ellipseColorMap.put(ellipse, c);
}
}
repaint();
}
}
/*
* This method will set the dimensions of the JFrame equal to the preferred H x W
*/
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
/*
* Used for button click action to change all ellipses to ACTIVE_COLOR
*/
public void activateAll(){
for (Ellipse2D ellipse : ellipses){
ellipseColorMap.put(ellipse, ACTIVE_COLOR);
}
repaint();
}
/*
* Used for button click action to change all ellipses to INACTIVE_COLOR
*/
public void deactivateAll(){
for (Ellipse2D ellipse : ellipses){
ellipseColorMap.put(ellipse, INACTIVE_COLOR);
}
repaint();
}
}
This method will set the dimensions of the JFrame equal to the preferred H x W
No it set the preferred size of the panel. The size of the frame will be the preferred size of all the components added to it plus the frame decorations (title bar, borders).
When I resize the window the Graphics2D objects reduce into a tiny rectangle.
The GridBagLayout respects the preferred size of the component. When there is not enough space to display the component it will shrink to its "minimum size".
You probably need to override the getMinimumSize() method to equal the preferred size. Then in this case the component should just be truncated if space is not available.
If you want you actually painting to shrink then you need to build the logic into your painting code so that the painting is done relative to the space available on the panel.
Try adding your 2D object to a JLabel as BufferedImage of ImageIcon. You can do this by:
JLabel label2 = new JLabel(new ImageIcon(//Location of your Image);
Or I think you can also add Graphics2D objects directly creating them inside label bu I'm not sure about that

How do i remove an object frame jframe then add another (with code) [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I have written a program that paints 5 pictures onto a canvas in jframe.
I have now added a jtextfield so that the user can input a number using an actionlistener.
Ideally, the number that the user enters should then produce that amount of pictures on a new canvas.
problem is, i cant remove the canvas object and add a new canvas with the new amount of pictures on it.
please help
public class TaxiFrame extends JFrame implements ActionListener {
private JLabel L1 = new JLabel("Number of Taxis:");
private JLabel L2 = new JLabel("Type an integer and press enter");
private JTextField t1 = new JTextField (" ");
public TaxiFrame() {
super("This is the Frame");
setSize(600, 400);
getContentPane().setBackground(Color.CYAN);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new BorderLayout(10, 10));
Random rx = new Random();
Random ry = new Random();
for(int i = 0; i < 5; i ++)
{
TaxiCanvas tax = new TaxiCanvas();
tax.setBounds(rx.nextInt(600 - 100), ry.nextInt(400 - 100), 100, 100);
add(tax);
}
JPanel p = new JPanel();
p.setOpaque(false);
p.add(L1);
getContentPane().
add("South", p);
p.setOpaque(false);
p.add(t1);
getContentPane().
add("South", p);
p.setOpaque(false);
p.add(L2);
getContentPane().
add("South", p);
setVisible(true);
t1.addActionListener(this);
}
public static void main(String[] args) {
new TaxiFrame();
}
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == t1)
{
if(Integer.parseInt(t1.getText()) > 0)
{
getContentPane().removeAll();
TaxiCanvas tax = new TaxiCanvas();
add(tax);
}
}
}
}
thanks alot
taxi canvas code is
import java.awt.*;
import javax.swing.*;
public class TaxiCanvas extends JComponent
{
private Taxi taxi = new Taxi();
public void paint(Graphics g)
{
taxi.paint(g);
}
}
taxi code
import java.awt.*;
public class Taxi
{
public void paint(Graphics g)
{
// drawing the car body
g.setColor(Color.yellow);
g.fillRect(0,10, 60, 15);
// drawing the wheels
g.setColor(Color.black);
g.fillOval(10, 20, 12, 12); // left wheel
g.fillOval(40, 20, 12, 12); // right wheel
int x[] = {10, 20, 40, 50}; // coordinate arrays for the
int y[] = {10, 0, 0, 10}; // car cabin
g.setColor(Color.yellow);
g.fillPolygon(x, y, 4); // drawing the cabin in yellow
g.setColor(Color.black);
g.drawString("20", 25, 22);
g.drawLine(0, 25, 60, 25);
}
}
When removing and adding components you need to revalidate() and repaint()
Instead of adding and removing containers consider using a CardLayout that will "layer" your containers and let you navigate through them. See How to use CardLayout
Don't override the paint method of JComponent. instead override paintComponent and make sure to call super.paintComponent as not to break the paint chain and probably leaving you with paint artifacts.
Dont use this deprecated add("South", p); method. Instead use add(p, BorderLayout.SOUTH)
Trying to tax.setBounds will do nothing, as far as placement, as your layout is set (not null)
You are trying to add to "South" a bunch of times. Each position can only hold one component
When adding to BorderLayout, if you don't specify a position when adding, it will automatically get added to the CENTER. So if you try to add multiple components without specify a position, only the last component you add will be shown.
Swing apps should be run on the Event Dispatch Thread (EDT). You can do so by wrapping your code in your main in a SwingUtilities.invokeLater.... See more at Initial Threads
Honestly I have no idea what your code is attempting to do, but look at RadioDef's comment below, see if it means anything to you.
If you want to add multiple Taxi objects to your TaxiCanvas, see this answer where you can use a List of Taxi objects and iterate through them in the paintComponent method.
I implemented many of the suggestions by #peeskillet as well as cleaned up the code a little and here is the result.
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
import java.awt.*;
public class TaxiFrame
extends JFrame
implements ActionListener {
private JLabel label1 = new JLabel("Number of Taxis:");
private JLabel label2 = new JLabel("Type an integer and press enter");
private JTextField inputField = new JTextField(10);
private JPanel taxiPanel = new JPanel();
private Dimension tpSize = new Dimension(600, 400);
private Random rand = new Random();
public TaxiFrame() {
super("This is the Frame");
getContentPane().setBackground(Color.CYAN);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new BorderLayout(10, 10));
taxiPanel.setLayout(null);
taxiPanel.setOpaque(false);
taxiPanel.setPreferredSize(tpSize);
add(taxiPanel, BorderLayout.CENTER);
JPanel p = new JPanel();
p.setOpaque(false);
p.add(label1);
p.add(inputField);
p.add(label2);
add(p, BorderLayout.SOUTH);
inputField.addActionListener(this);
inputField.setText("5");
addNewTaxis(5);
pack();
setResizable(false);
setLocationRelativeTo(null);
setVisible(true);
}
private void addNewTaxis(int numTaxis) {
for(int i = 0; i < numTaxis; i++) {
addNewTaxi();
}
}
private void addNewTaxi() {
TaxiCanvas tc = new TaxiCanvas();
tc.setBounds(
rand.nextInt(tpSize.width - 100),
rand.nextInt(tpSize.height - 100),
100, 100
);
taxiPanel.add(tc);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == inputField) {
int numTaxis = Integer.parseInt(inputField.getText());
if(numTaxis > 0) {
taxiPanel.removeAll();
addNewTaxis(numTaxis);
taxiPanel.revalidate();
repaint();
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TaxiFrame();
}
});
}
public static class TaxiCanvas
extends JComponent {
private Taxi taxi = new Taxi();
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
taxi.paint(g);
}
}
public static class Taxi {
public void paint(Graphics g) {
// drawing the car body
g.setColor(Color.yellow);
g.fillRect(0,10, 60, 15);
// drawing the wheels
g.setColor(Color.black);
g.fillOval(10, 20, 12, 12); // left wheel
g.fillOval(40, 20, 12, 12); // right wheel
int x[] = {10, 20, 40, 50}; // coordinate arrays for the
int y[] = {10, 0, 0, 10}; // car cabin
g.setColor(Color.yellow);
g.fillPolygon(x, y, 4); // drawing the cabin in yellow
g.setColor(Color.black);
g.drawString("20", 25, 22);
g.drawLine(0, 25, 60, 25);
}
}
}
Please don't accept this answer, I just wanted to show they were good suggestions and show the working code. There were many small Swing-related bugs but otherwise the code works.

Categories

Resources