Adding elements to JPanel - java

Why does "drawing" not appear here? I am adding it to a different JPanel then adding everything to another JPanel and returning that. However, all i see is the TrackBall
public class Draw extends JFrame
{
private JSplitPane itemPane;
private Point position = null;
public Draw()
{
// Set the layout to a grid
setLayout ( new BorderLayout (5,5));
// Set the properties of the window
setTitle ("Emulator");
setSize ( 900, 700);
setDefaultCloseOperation (EXIT_ON_CLOSE);
setBackground ( new Color (15, 255, 10));
// Add the components
addComponents ();
}
public static void startWindowsGui()
{
// We are in the static main, set the form to invoke later
SwingUtilities.invokeLater ( new Runnable()
{
public void run()
{
// Create a new instance of server and set it to visible
Draw gui = new Draw();
gui.setVisible (true);
}
} );
}
private void addComponents()
{
// Create the main and an itemPane
JSplitPane mainPane = new JSplitPane ( JSplitPane.HORIZONTAL_SPLIT );
setItemPane(new JSplitPane ( JSplitPane.VERTICAL_SPLIT ));
mainPane.add ( createPane ( ), JSplitPane.LEFT );
mainPane.add ( getItemPane(), JSplitPane.RIGHT );
mainPane.setOneTouchExpandable ( true );
getItemPane().setOpaque(true);
getItemPane().setBackground(new Color(0xffffffc0));
JPanel p = new JPanel();
this.getItemPane().add(p);
add ( mainPane, BorderLayout.CENTER );
}
public static void main(final String[] args)
{
Runnable gui = new Runnable()
{
#Override
public void run()
{
new Draw().setVisible(true);
}
};
SwingUtilities.invokeLater(gui);
}
private class Drawing extends JPanel {
private static final long serialVersionUID = 1L;
private final Point position;
public Drawing(Point position) {
this.position = position;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.RED);
g2.fillOval(160 + position.x, 160 - position.y, 15, 15);
}
}
private JPanel createPane()
{
// Create the feedPanel
JPanel panel = new JPanel ( );
JPanel panel2 = new JPanel ( );
JPanel panel3 = new JPanel ( );
this.position = new Point();
TrackBall myJoystick = new TrackBall(150, position, 100);
panel.add(myJoystick, BorderLayout.PAGE_END);
Drawing drawing = new Drawing(position);
panel2.add(drawing, BorderLayout.PAGE_START);
panel3.add(panel2);
panel3.add(panel);
return panel3;
}
public JSplitPane getItemPane() {return itemPane;}
public void setItemPane(JSplitPane itemPane) {this.itemPane = itemPane;}
}

3 issues
panel2 requires BorderLayout rather than the default FlowLayout for the BorderLayout.PAGE_START constraint to be used
The class Drawing is required to override getPreferredSize
The Dimension specified by getPreferredSize should be large enough to accommodate the position specified in the constructor of Drawing
Read: Changing preferred size of a Swing component

Related

Repaint Isn't doing anything

I am trying to make a rectangle change color with GUI sliders. I know this can be done by changing the background but I'm trying to use repaint.
I know that repaint holds the requests and executes at will almost. I'm trying to find a workaround because I'm stuck.
I've read up on repaint(); and repaintManager and tried manipulating my code but I'm still unable to get my desired output.
Any help would be appreciated.
import java.awt.BorderLayout;
import javax.swing.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
*
*
*/
public class MyColorChooser2 extends JPanel {
private JFrame frame;
private JLabel redLabel, greenLabel, blueLabel;
private JSlider redSlider, greenSlider, blueSlider;
private JTextField redTextField, greenTextField, blueTextField;
private JPanel redPanel, greenPanel, bluePanel, colorPanel, paintPanel;
private int holdNbr1, holdNbr2, holdNbr3;
DrawPanel rect = new DrawPanel();
public MyColorChooser2() {
JFrame frame = new JFrame();
frame.setTitle("Color Chooser");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// set up labels
redLabel = new JLabel("Red:");
greenLabel = new JLabel("Green:");
blueLabel = new JLabel("Blue:");
// set up sliders and register their event handler:
redSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 50);
redSlider.setMajorTickSpacing(10); // create tick every 10
redSlider.setPaintTicks(true); // paint ticks on slider
greenSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 100);
greenSlider.setMajorTickSpacing(10); // create tick every 10
greenSlider.setPaintTicks(true); // paint ticks on slider
blueSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 200);
blueSlider.setMajorTickSpacing(10); // create tick every 10
blueSlider.setPaintTicks(true); // paint ticks on slider
//slider event handling:
SliderHandler sliderHandler = new SliderHandler();
redSlider.addChangeListener(sliderHandler);
greenSlider.addChangeListener(sliderHandler);
blueSlider.addChangeListener(sliderHandler);
//set up textFields and register their event handler:
redTextField = new JTextField(3);
redTextField.setText("50"); //initialize
redTextField.setEditable(false);
redTextField.setText("" + redSlider.getValue());
greenTextField = new JTextField(3);
greenTextField.setText("100"); //initialize
greenTextField.setEditable(false);
greenTextField.setText("" + greenSlider.getValue());
blueTextField = new JTextField(3);
blueTextField.setText("200"); //initialize
blueTextField.setEditable(false);
blueTextField.setText("" + blueSlider.getValue());
// build colorPanel:
// build redPanel:
redPanel = new JPanel();
redPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
redPanel.add(redLabel);
redPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
redPanel.add(redSlider);
redPanel.add(redTextField);
// build greenPanel:
greenPanel = new JPanel();
greenPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
greenPanel.add(greenLabel);
greenPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
greenPanel.add(greenSlider);
greenPanel.add(greenTextField);
// build bluePanel:
bluePanel = new JPanel();
bluePanel.setLayout(new FlowLayout(FlowLayout.LEFT));
bluePanel.add(blueLabel);
bluePanel.setLayout(new FlowLayout(FlowLayout.CENTER));
bluePanel.add(blueSlider);
bluePanel.add(blueTextField);
colorPanel = new JPanel();
colorPanel.add(redPanel);
colorPanel.add(greenPanel);
colorPanel.add(bluePanel);
frame.setLayout(new BorderLayout());
frame.add(rect, BorderLayout.CENTER);
frame.add(colorPanel, BorderLayout.SOUTH);
frame.setPreferredSize(new Dimension(900, 300));
frame.setVisible(true);
frame.pack();
}
public class DrawPanel extends JPanel {
private Color color;
private int red = 50, blue = 100, green = 200;
private Graphics g;
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
changeColor();
g.setColor(color);
g.fillRect(10, 10, 880, 200);
g.dispose();
}
public void DrawPanel(Color c) {
color = c;
red = color.getRed();
green = color.getGreen();
blue = color.getBlue();
}
void changeColor() {
color = new Color(red, green, blue);
this.color = color;
}
public void setRed(int r) {
red = r;
changeColor();
}
public void setBlue(int b) {
blue = b;
changeColor();
}
public void setGreen(int g) {
green = g;
changeColor();
}
}
private class SliderHandler implements ChangeListener {
#Override
public void stateChanged(ChangeEvent e) {
JSlider change = (JSlider) e.getSource();
DrawPanel draw = new DrawPanel();
int value;
if (change == redSlider) {
value = change.getValue();
redTextField.setText(String.valueOf(value));
draw.setRed(value);
} else if (change == greenSlider) {
value = change.getValue();
greenTextField.setText(String.valueOf(value));
draw.setGreen(value);
} else if (change == blueSlider) {
value = change.getValue();
blueTextField.setText(String.valueOf(value));
draw.setBlue(value);
}
draw.changeColor();
draw.repaint();
}
}
public static void main(String args[]) {
MyColorChooser2 color = new MyColorChooser2();
}
}
It's not that it isn't doing anything. The problem is that you're stuck, because every time you make a change you're trying to update a different component. You're recreating multiple panels in your state changed.
I've added comments about the changes I've done to make it work properly. If you need more help, just ask. Cheers!
Would you care trying this code:
public class MyColorChooser2 extends JPanel {
private JFrame frame;
private DrawPanel drawPanel;
private JLabel redLabel, greenLabel, blueLabel;
private JSlider redSlider, greenSlider, blueSlider;
private JTextField redTextField, greenTextField, blueTextField;
private JPanel redPanel, greenPanel, bluePanel, colorPanel, paintPanel;
private int holdNbr1, holdNbr2, holdNbr3;
private Color initialColor = Color.RED;
public MyColorChooser2() {
JFrame frame = new JFrame();
frame.setTitle("Color Chooser");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Let DrawPanel choose the initial color. I don't care.
drawPanel = new DrawPanel();
// This way I control what is the initial color
//drawPanel = new DrawPanel(initialColor);
// set up labels
redLabel = new JLabel("Red:");
greenLabel = new JLabel("Green:");
blueLabel = new JLabel("Blue:");
// set up sliders and register their event handler:
redSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 255, initialColor.getRed());
redSlider.setMajorTickSpacing(10); // create tick every 10
redSlider.setPaintTicks(true); // paint ticks on slider
greenSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 255, initialColor.getGreen());
greenSlider.setMajorTickSpacing(10); // create tick every 10
greenSlider.setPaintTicks(true); // paint ticks on slider
blueSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 255, initialColor.getBlue());
blueSlider.setMajorTickSpacing(10); // create tick every 10
blueSlider.setPaintTicks(true); // paint ticks on slider
// slider event handling:
SliderHandler sliderHandler = new SliderHandler();
redSlider.addChangeListener(sliderHandler);
greenSlider.addChangeListener(sliderHandler);
blueSlider.addChangeListener(sliderHandler);
// set up textFields and register their event handler:
redTextField = new JTextField(3);
redTextField.setText("50"); // initialize
redTextField.setEditable(false);
redTextField.setText("" + redSlider.getValue());
greenTextField = new JTextField(3);
greenTextField.setText("100"); // initialize
greenTextField.setEditable(false);
greenTextField.setText("" + greenSlider.getValue());
blueTextField = new JTextField(3);
blueTextField.setText("200"); // initialize
blueTextField.setEditable(false);
blueTextField.setText("" + blueSlider.getValue());
// build colorPanel:
// build redPanel:
redPanel = new JPanel();
redPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
redPanel.add(redLabel);
redPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
redPanel.add(redSlider);
redPanel.add(redTextField);
// build greenPanel:
greenPanel = new JPanel();
greenPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
greenPanel.add(greenLabel);
greenPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
greenPanel.add(greenSlider);
greenPanel.add(greenTextField);
// build bluePanel:
bluePanel = new JPanel();
bluePanel.setLayout(new FlowLayout(FlowLayout.LEFT));
bluePanel.add(blueLabel);
bluePanel.setLayout(new FlowLayout(FlowLayout.CENTER));
bluePanel.add(blueSlider);
bluePanel.add(blueTextField);
colorPanel = new JPanel();
colorPanel.add(redPanel);
colorPanel.add(greenPanel);
colorPanel.add(bluePanel);
frame.setLayout(new BorderLayout());
frame.add(drawPanel, BorderLayout.CENTER);
frame.add(colorPanel, BorderLayout.SOUTH);
frame.setPreferredSize(new Dimension(900, 300));
frame.setVisible(true);
frame.pack();
}
private class DrawPanel extends JPanel {
private Color color;
private int red = 255, blue = 0, green = 0;
#Override
protected void paintComponent(Graphics g) {
// I've removed the call to changeColor because it was creating
// an infinite loop of revalidates and repaints.
// Now, the paintComponent just finishes the job it was required to.
super.paintComponent(g);
g.setColor(color);
g.fillRect(10, 10, 880, 200);
}
public DrawPanel() {
this(Color.BLUE);
}
public DrawPanel(Color c) {
color = c;
red = color.getRed();
green = color.getGreen();
blue = color.getBlue();
// I'm calling this first repaint here just to make
// sure the panel is initiated the way we want with
// the given Color
repaint();
}
void changeColor() {
color = new Color(red, green, blue);
// We just need to change the color and call this repaint here
// so that the paintComponent can do its job
repaint();
}
public void setRed(int r) {
red = r;
changeColor();
}
public void setBlue(int b) {
blue = b;
changeColor();
}
public void setGreen(int g) {
green = g;
changeColor();
}
}
private class SliderHandler implements ChangeListener {
#Override
public void stateChanged(ChangeEvent e) {
JSlider change = (JSlider) e.getSource();
int value;
// I've removed this line of code because you were
// recreating the drawingPanel. That's not what you want.
// You want to reuse the same panel.
// DrawPanel draw = new DrawPanel();
if (change == redSlider) {
value = change.getValue();
redTextField.setText(String.valueOf(value));
drawPanel.setRed(value);
} else if (change == greenSlider) {
value = change.getValue();
greenTextField.setText(String.valueOf(value));
drawPanel.setGreen(value);
} else if (change == blueSlider) {
value = change.getValue();
blueTextField.setText(String.valueOf(value));
drawPanel.setBlue(value);
}
// You don't need to call those methods, because the
// changeColor will be called by the settings
// of Red, Green and Blue
// draw.changeColor();
// draw.repaint();
}
}
public static void main(String args[]) {
MyColorChooser2 color = new MyColorChooser2();
}
}

In Java, how can I combine CardLayout and GridBagLayout and still be able to switch panels?

New to Java and very new to Java's GUI classes. I'm making a GUI to showcase a few games, but am having difficulties switching panels. I read about CardLayout but I'm having an issue implementing it because I can't get the JPanels that hold the different games' GUIs to send their events back to the class that uses the CardLayout. (This is probably where I'm going wrong -- I can't get my head around how to structure this properly.)
This is my main menu (called mainContainer):
This is the overall structure of the GUI driver:
public class CasinoDriverGUI {
//CardLayout is here in the main method Container contentPane.add(cardLayout)
public static void main(String[] args) throws IOException
//MainContainer is MenuScreen: GridBagLayout for nice button placement
static class MainContainer extends JPanel implements ActionListener{...}
static class CrapsContainer extends JPanel implements ActionListener{...}
static class PokerContainer extends JPanel implements ActionListener{...}
//Button with custom look
class CButton extends JButton
}//end CasinoDriverGUI
Here is the main method: It grabs an image from a website and then adds the menu screen (mainContainer) to the contentPane. The menu screen uses GridBagLayout, but it's where the button components are added. Because of this, I can't figure out how to get the CardLayout of the contentPane to listen to the menu screen's buttons. I tried using ContainerListener but that seemed to be a dead end.
public class CasinoDriverGUI {
public static void main(String[] args) throws IOException {
// load the texture resource image
System.out.println("Please wait, Loading Texture : http://www.pngall.com/wp-content/uploads/2016/04/Casino-PNG-Pic.png");
MainContainer.textureImg = ImageIO.read(new URL("http://www.pngall.com/wp-content/uploads/2016/04/Casino-PNG-Pic.png"));
System.out.println("Loading finished. Starting the Casino!");
MainContainer.textureImg = MainContainer.textureImg.getSubimage(0, 0, 580, 309);
// Starting the Swing GUI in the EDT
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
final CardLayout cardLayout = new CardLayout();
JFrame frame = new JFrame("Midnight Casino");
// frame about the size of background src image
frame.setPreferredSize(new Dimension(580, 329));
final Container contentPane = frame.getContentPane();
contentPane.setLayout(cardLayout);
MainContainer mainContainer = new MainContainer();
mainContainer.setPreferredSize( frame.getPreferredSize() );
contentPane.add(mainContainer, "mainContainer");
frame.pack();
frame.setLocationRelativeTo(null);
frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
As I have it so far, I have just tried using the "menu screen" (mainContainer) to instantiate all the games' panels and use an ActionListener on some buttons to simply call thisGame.setVisible(true). but this is forcing the window to be minimized and re-opened for any change to be detectable.Edit: fixed this.
Any advice on how I can restructure this code to be able to switch the panels from the menu screen to the different game's panels? (Code is below, but the craps and poker GUIs are incomplete.. just using the code as placeholders.
public class CasinoDriverGUI {
public static void main(String[] args) throws IOException {
// load the texture resource image
System.out.println("Please wait, Loading Texture : http://www.pngall.com/wp-content/uploads/2016/04/Casino-PNG-Pic.png");
MainContainer.textureImg = ImageIO.read(new URL("http://www.pngall.com/wp-content/uploads/2016/04/Casino-PNG-Pic.png"));
System.out.println("Loading finished. Starting the Casino!");
MainContainer.textureImg = MainContainer.textureImg.getSubimage(0, 0, 580, 309);
// Starting the Swing GUI in the EDT
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
final CardLayout cardLayout = new CardLayout();
JFrame frame = new JFrame("Midnight Casino");
// frame about the size of background src image
frame.setPreferredSize(new Dimension(580, 329));
final Container contentPane = frame.getContentPane();
contentPane.setLayout(cardLayout);
MainContainer mainContainer = new MainContainer();
mainContainer.setPreferredSize( frame.getPreferredSize() );
contentPane.add(mainContainer, "mainContainer");
frame.pack();
frame.setLocationRelativeTo(null);
frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
static class MainContainer extends JPanel implements ActionListener
{
public BufferedImage gradientImage = null;
public static BufferedImage textureImg; // static for ease
public static boolean loadingFinished = false;
protected JButton pokerJBtn;
protected JButton crapsJBtn;
CrapsContainer crapsContainer;
PokerContainer pokerContainer;
public MainContainer() {
setBorder(new EmptyBorder(50, 50, 50, 50)); // setting the insets
setLayout(new GridBagLayout());
// working with GridBagConstraints
GridBagConstraints labCnst = new GridBagConstraints();
GridBagConstraints txtCnst = new GridBagConstraints();
labCnst.ipady = txtCnst.ipady = 10;
labCnst.fill = GridBagConstraints.HORIZONTAL;
labCnst.gridwidth = 1;
labCnst.weightx = 0.3;
labCnst.gridx = 2;
labCnst.gridy = 2;
labCnst.ipady = 13;
labCnst.insets = new Insets(0, 0, 0, 150);
pokerJBtn = new CButton("5-Card Poker");
add(pokerJBtn, labCnst);
labCnst.gridx = 2;
labCnst.gridy = 20;
labCnst.ipady = 13;
labCnst.insets = new Insets(0, 0, 0, 150);
crapsJBtn = new CButton("Craps");
add(crapsJBtn, labCnst);
crapsContainer = new CrapsContainer();
pokerContainer = new PokerContainer();
add(crapsContainer);
add(pokerContainer);
crapsContainer.setVisible(false);
pokerContainer.setVisible(false);
//Add Action Listeners
crapsJBtn.addActionListener(this);
pokerJBtn.addActionListener(this);
}
public void changeCompFont(JComponent comp)
{
comp.setForeground(Color.WHITE);
comp.setFont(getFont().deriveFont(Font.BOLD, 13));
}
// To PAINT THE TEXTURE ABOVE THE COMPONENTS
#Override
public void paint(Graphics g)
{
super.paint(g);
Graphics2D g2d = (Graphics2D)g.create(); // cloning
Rectangle2D txRect = new Rectangle2D.Double(0, 0, textureImg.getWidth(), textureImg.getHeight());
TexturePaint txPaint = new TexturePaint(textureImg, txRect);
g2d.setPaint(txPaint);
//make the texture transparent
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.233f));
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.dispose();// disposing the graphics object
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if(gradientImage==null || gradientImage.getHeight() != getHeight() )
{
gradientImage = createGradientImg();
}
g2d.drawImage(gradientImage, 0, 0, getWidth(), getHeight(), this);
g2d.dispose();
}
public BufferedImage createGradientImg()
{
BufferedImage image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
// background gradient paint, linear gradient paint for the background
// Gradient paint rendering could be made more optimized
LinearGradientPaint lgrPaint = new LinearGradientPaint(0.0f, 0.0f, getWidth(), getHeight(),
new float[] { 0.0f, 0.5f, 0.6f, 1.0f },
new Color[] { new Color(0x0530E),// new Color[] { new Color(0x002AFF),
new Color(0x0A31B),
new Color(0x0A31B),
new Color(0x0530E ) });
Graphics2D g2d = (Graphics2D) image.getGraphics();
g2d.setPaint(lgrPaint);
//g2d.shear(0.2, 0);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.dispose();
g2d.drawImage(textureImg, 0, 0, getWidth(), getHeight(), null);
return image;
}
#Override
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == pokerJBtn)
{
pokerContainer.setVisible(true);
}
else if (e.getSource() == crapsJBtn){
this.setVisible(false);
invalidate();
crapsContainer.setVisible(true);
revalidate();
repaint();
}
}
}
//Either Flow, Border, or GridBag Layout
static class CrapsContainer extends JPanel implements ActionListener
{...}
//Either Flow, Border, or GridBag Layout
static class PokerContainer extends JPanel implements ActionListener
{...}
//Custom Button to change aesthetic look
class CButton extends JButton
{...}
}

Translucent internal frames - is that possible in java?

Is there any way I can make translucent JInternalFrame uing swing?
All I found is option for JFrame(not internal one) which is not what I need.
You should be able to use a JLayer. You could start with the layout painting a fully opaque layer the same color as the background of the desktop pane. Then you change the alpha value to approach cell until you have full transparency.
See the section from the Swing tutorial on How to Decorate Components With the JLayer Class for more information and an example of painting with transparency.
If you only care about the background you can use the Alpha Container when using components with transparency:
JPanel content = new JPanel( new BorderLayout() );
content.setBackground( new Color(0, 0, 0, 0) );
internalFrame.setContentPane(new AlphaContainer(content));
internalFrame.setOpaque(false);
You can then change the alpha value of the content panel to your desired transparency.
Edit:
Here is may attempt at animating the transparency of an internal frame and its components:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class TransparentInternalFrame extends JInternalFrame implements ActionListener
{
static int openFrameCount = 0;
static final int xOffset = 30, yOffset = 30;
private float alpha = 0.0f;
private Timer timer = new Timer(500, this);
public TransparentInternalFrame()
{
super("Document #" + (++openFrameCount), true, true, true, true);
setSize(300,300);
setLocation(xOffset * openFrameCount, yOffset * openFrameCount);
setVisible( true );
}
#Override
public void paint(Graphics g)
{
g.setColor( getDesktopPane().getBackground() );
g.fillRect(0, 0, getWidth(), getHeight());
Graphics2D g2 = (Graphics2D)g.create();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
super.paint(g2);
}
public void showFrame()
{
timer.start();
}
public void hideFrame()
{
alpha = 0.0f;
repaint();
}
#Override
public void actionPerformed(ActionEvent e)
{
alpha += .05f;
alpha = Math.min(1.0f, alpha);
System.out.println(alpha);
if (alpha >= 1.0f)
timer.stop();
repaint();
}
private static void createAndShowGUI()
{
JDesktopPane desktop = new JDesktopPane();
desktop.setBackground( Color.YELLOW );
TransparentInternalFrame tif = new TransparentInternalFrame();
desktop.add( tif );
tif.add(new JButton("Hello"), BorderLayout.PAGE_START);
JButton show = new JButton( "Show Internal Frame" );
show.addActionListener( new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
tif.showFrame();
}
});
JButton hide = new JButton( "Hide Internal Frame" );
hide.addActionListener( new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
tif.hideFrame();
}
});
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(show, BorderLayout.PAGE_START);
frame.add(desktop);
frame.add(hide, BorderLayout.PAGE_END);
frame.setLocationByPlatform( true );
frame.setSize(500, 500);
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}

How to dynamically add a new customized button?

I am trying to have my interface dynamically generate a customized button when I click a button. I searched several answers like this, but somehow it does not work. Is there any mistake with my current code below?
public class MainWindow {
private JFrame frame;
private JPanel panel;
private JPanel panel_1;
private JPanel panel_2;
private JSplitPane splitPane;
private JButton btnSearch;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainWindow window = new MainWindow();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public MainWindow() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 645, 438);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
frame.getContentPane().add(panel, BorderLayout.CENTER);
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
splitPane = new JSplitPane();
panel.add(splitPane);
panel_1 = new JPanel();
splitPane.setLeftComponent(panel_1);
btnSearch = new JButton("Search");
GridBagConstraints gbc_btnSearch = new GridBagConstraints();
gbc_btnSearch.gridx = 0;
gbc_btnSearch.gridy = 10;
panel_1.add(btnSearch, gbc_btnSearch);
panel_2 = new JPanel();
splitPane.setRightComponent(panel_2);
btnSearch.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
addButton();
}
});
}
protected void addButton() {
MyButton hahaButton = new MyButton("haha");
panel_2.add(hahaButton);
panel_2.add(new JButton());
panel_2.revalidate();
panel_2.repaint();
}
And this is the definition of the MyButton:
public class MyButton extends JButton {
private static final long serialVersionUID = 1L;
private Color circleColor = Color.BLACK;
public MyButton(String label) {
super(label);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension originalSize = super.getPreferredSize();
int gap = (int) (originalSize.height * 0.2);
int x = originalSize.width + gap;
int y = gap;
int diameter = originalSize.height - (gap * 2);
g.setColor(circleColor);
g.fillOval(x, y, diameter, diameter);
}
#Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
size.width += size.height;
return size;
}
}
I just tried your sourcecode and it works as expected: everytime I klick the search button on the left side of the split-pane, 2 buttons are added to the panel on the right side of the panel (one with the black filled circle and a button without a label).
What doesn't work for you? I'm using java 1.6 on Mac OSX, but this should work with earlier versions on other platforms as well......
As Dieter Rehbein pointed out, the code you have does compile and run.
However, it was rather sloppy and convoluted, as if you copied and pasted different sources together.
I took a few minutes and cleaned it up some, hope it helps.
public class MainWindow
{
public static void main( String[] args )
{
new MainWindow();
}
public MainWindow()
{
// Create the split pane
JSplitPane jSplitPane = new JSplitPane();
final JPanel leftPanel = new JPanel();
final JPanel rightPanel = new JPanel();
jSplitPane.setLeftComponent( leftPanel );
jSplitPane.setRightComponent( rightPanel );
// Create the button
JButton jButton = new JButton( "Generate" );
leftPanel.add( jButton );
jButton.addMouseListener( new MouseAdapter()
{
#Override
public void mouseClicked( MouseEvent e )
{
addButtons( rightPanel );
}
} );
// Create the panel
JPanel jPanel = new JPanel();
jPanel.setLayout( new BoxLayout( jPanel , BoxLayout.X_AXIS ) );
jPanel.add( jSplitPane );
// Create the frame
JFrame jFrame = new JFrame();
jFrame.setBounds( 100 , 100 , 645 , 438 );
jFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
jFrame.getContentPane().add( jPanel , BorderLayout.CENTER );
// Show the frame
jFrame.setVisible( true );
}
private void addButtons( JPanel jPanel )
{
addButton( jPanel , "Default" , null );
addButton( jPanel , "Red" , Color.RED );
addButton( jPanel , "Yellow" , Color.YELLOW );
addButton( jPanel , "Blue" , Color.BLUE );
addButton( jPanel , "Green" , Color.GREEN );
}
protected void addButton( JPanel jPanel , String label , Color color )
{
jPanel.add( new MyButton( label , color ) );
jPanel.revalidate();
jPanel.repaint();
}
public class MyButton extends JButton
{
private static final long serialVersionUID = 1L;
private Color color = null;
public MyButton( String label , Color color )
{
super( label );
this.color = color;
}
#Override
protected void paintComponent( Graphics graphics )
{
super.paintComponent( graphics );
if ( color != null )
{
Dimension dimension = super.getPreferredSize();
int gap = ( int ) ( dimension.height * 0.2 );
int diameter = dimension.height - ( gap * 2 );
graphics.setColor( color );
graphics.fillOval( dimension.width + gap , gap , diameter , diameter );
}
}
#Override
public Dimension getPreferredSize()
{
Dimension size = super.getPreferredSize();
size.width += size.height;
return size;
}
}
}

Java repainting when pushing a button

I've hit a wall (in my brain) trying to update my board on button presses. Am I right in thinking that the GameBoard class is the one that needs to be repaint()ed?
GameBoard.java
public class GameBoard extends Panel {
static Compass compass = new Compass();
private static final long serialVersionUID = 1;
Graphics2D g2d;
static final Dimension WINDOW_SIZE = new Dimension(1150, 800);
public void boardMaker() throws Exception {
JFrame frame = new JFrame("Display image");
JPanel panel = new JPanel();
/* unimportant stuff
.....
*/
//
DieRoll roll = new DieRoll("Roll Dies");
roll.setC(compass);
roll.setG2D(g2d);
//
Button button = new Button("new");
button.setGameBoard(this);
JPanel buttonPanel = new JPanel();
buttonPanel.add(button);
buttonPanel.add(roll);
buttonPanel.setPreferredSize(new Dimension(200,100));
frame.getContentPane().add(buttonPanel, BorderLayout.NORTH);
//
frame.getContentPane().add(panel);
frame.setVisible(true);
}
public void paint(Graphics g) {
// not important I think
}
}
Button.java
public class Button extends JButton implements ActionListener {
private static final long serialVersionUID = 1L;
JPanel panel = new JPanel();
JFrame frame = new JFrame();
Compass c = new Compass();
GameBoard gb = new GameBoard();
Button(String text) {
this.setText(text);
this.addActionListener(this);
}
void setGameBoard(GameBoard gb) {
this.gb = gb;
}
#Override
public void actionPerformed(ActionEvent e) {
gb.g2d.setColor(Color.black);
gb.g2d.fillRect(100, 100, 100, 200);
gb.repaint();
}
}
This gives a null pointer exception. So any idea how to repaint my GameBoard? I'm not mad if I've to rewrite everything because of stupidity! ;)
Thanks
You have the wrong idea about how to draw in Java. Components like Panels draw themselves, and all drawing takes place on the UI thread.
Check out this tutorial: docs.oracle.com/javase/tutorial/2d/index.html
The article Painting in AWT and Swing may offer some perspective on application-triggered painting. The example below illustrates the principle. Note that setForeground() calls repaint() automatically because the foreground color is a bound property, but you can always call it yourself.
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;
public class SwingPaint {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame f = new JFrame();
final GamePanel gp = new GamePanel();
f.add(gp);
f.add(new JButton(new AbstractAction("Update") {
#Override
public void actionPerformed(ActionEvent e) {
gp.update();
}
}), BorderLayout.SOUTH);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
private static class GamePanel extends JPanel {
private static final Random r = new Random();
public GamePanel() {
this.setForeground(new Color(r.nextInt()));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
public void update() {
this.setForeground(new Color(r.nextInt()));
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension size = this.getSize();
int d = Math.min(size.width, size.height) - 10;
int x = (size.width - d) / 2;
int y = (size.height - d) / 2;
g.fillOval(x, y, d, d);
g.setColor(Color.blue);
g.drawOval(x, y, d, d);
}
}
}

Categories

Resources