I have a JPanel that acts as topbar for my application, I am trying to design the topbar buttons now, But I am facing an Issue.
as you can see when I hover over it the red is not filling the panel, I want the red to be a full square. and remain the same size for topbar and icon size. The result I expect is
as you can see the color is filled within the full bar. I would like to recreate this.
So here is the code as follows a Custom JButtonClass to create the Hover Effect.
public class LynxButton extends JButton {
public LynxButton(){
super.setContentAreaFilled(false);
}
public LynxButton(String text) {
super(text);
super.setContentAreaFilled(false);
}
#Override
protected void paintComponent(Graphics g) {
Color pressedColor = ThemeManager.red_LYNX.darker();
if (getModel().isPressed()) {
g.setColor(pressedColor);
} else if (getModel().isRollover()) {
g.setColor(pressedColor);
} else {
g.setColor(getBackground());
}
g.fillRect(0, 0, getWidth(), getHeight());
super.paintComponent(g);
}
#Override
public void setContentAreaFilled(boolean b) {
}
}
and then we define the code using
LynxButton exitButton = new LynxButton();
exitButton.setIcon(...);
exitButton.setBorder(null);
I have tried to set the margin to see if it fixes the issue but again no luck with it.
exitButton.setMargin(new Insets(0, 0, 0, 0));
Edit: Forgot to show the JPanel Defination
JPanel buttonContainer = new JPanel(new FlowLayout(FlowLayout.RIGHT));
The buttonContainer fills the whole topbar, Confirmed it by removing the call to setBackgroundColor.
You didn't calculate the hgap and vgap from FlowLayout in. Those act like a natural border.
All you need to do is the alter the initialization of your JPanel to new JPanel(new FlowLayout(FlowLayout.RIGHT), 0, 0)
Example code:
public static void main(String[] args) {
JFrame f = new JFrame();
TestA b = new TestA("X");
JPanel buttonContainer = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));
buttonContainer.setBackground(Color.GREEN);
buttonContainer.add(b);
f.add(buttonContainer);
f.pack();
f.setVisible(true);
}
TestA is your LynxButton
class TestA extends JButton {
public TestA() {
super.setContentAreaFilled(false);
}
public TestA(String text) {
super(text);
super.setContentAreaFilled(false);
}
#Override
protected void paintComponent(Graphics g) {
Color pressedColor = Color.RED;
if (getModel().isPressed()) {
g.setColor(pressedColor);
} else if (getModel().isRollover()) {
g.setColor(pressedColor);
} else {
g.setColor(getBackground());
}
g.fillRect(0, 0, getWidth(), getHeight());
super.paintComponent(g);
}
#Override
public void setContentAreaFilled(boolean b) {
}
}
Related
My problem is pretty hard to explain. First of all, I have :
A JPanel (leftPanel)
A JScrollPane (lBar), which is created to scroll the leftPanel (--> new JScrollPane(leftPanel))
A button that adds a new panel in the leftPanel on each click
Here's the result :
https://www.youtube.com/watch?v=VFXwh_vofQI
There are two problems :
With 4 or 5 clicks, the panels are overriding themselves (strange)
(secondary)
I would like the button + panels to look nicer (instead
of a BIG CENTERED button)
The code I use :
ActionsPanel panel = new ActionsPanel();
JScrollPane lBar = new JScrollPane(leftPanel);
lBar.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
The ActionsPanel class :
public class ActionsPanel extends JPanel
{
private JButton newAction;
public ActionsPanel(final Editor editor)
{
this.newAction = new JButton("New");
this.newAction.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
getActions().add(new Action());
refresh();
}
});
setLayout(new GridLayout(0, 1));
refresh();
}
public void refresh()
{
removeAll();
add(newAction);
for (Action action : getActions())
{
ActionPanel panel = new ActionPanel(action);
panel.revalidate();
panel.repaint();
add(panel);
}
revalidate();
}
}
The ActionPanel class :
public class ActionPanel extends JPanel
{
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D graphics = (Graphics2D) g;
setSize(getWidth(), 100);
setLayout(new GridLayout(2, 1));
graphics.setColor(Color.GRAY);
graphics.drawRect(0, 0, getWidth(), getHeight());
graphics.setColor(Color.BLACK);
graphics.setStroke(new BasicStroke(2));
graphics.drawRect(0, 0, getWidth(), getHeight());
graphics.drawString("Ordinal : " + getOrdinal(), 5, 15);
}
}
How to change the color of rectangle ? I want change it to yellow color. I added g.setColor(Color.YELLOW); inside rectDraw, but the color of the rectangle still remain the same. Can someone tell me what wrong I did please?
public class SelectSeat {
static JFrame frame;
public JPanel createContentPane() throws IOException
{
JPanel totalGUI = new JPanel();
RectDraw rect= new RectDraw();
rect.setPreferredSize(new Dimension(330,35)); //for size
totalGUI.setLayout(null);
totalGUI.setBackground(Color.WHITE);
totalGUI.add(rect);
Dimension d = rect.getPreferredSize();
rect.setBounds(100, 20, d.width, d.height); // for location
return totalGUI;
}
void setVisible(boolean b) {
// TODO Auto-generated method stub
}
static void createAndShowGUI() throws IOException
{
JFrame.setDefaultLookAndFeelDecorated(true);
frame = new JFrame("Seat Selection");
//Create and set up the content pane.
SelectSeat demo = new SelectSeat();
frame.setContentPane(demo.createContentPane());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(535, 520);
frame.setLocation(500,220);
frame.setVisible(true);
}
private static class RectDraw extends JPanel
{
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.drawString("Movie Sceen", 130, 20);
}
}
}
How to change the color of rectangle ? I want change it to yellow color.
You need to set the color to yellow, followed by filling a rectangle the size of the component.
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.YELLOW);
g.fillRect(0,0,getWidth(), getHeight());
g.setColor(Color.BLUE);
g.drawString("Movie Sceen", 130, 20);
}
And for what its worth:
totalGUI.setLayout(null);
I would recommend against using null Layouts. Use a LayoutManager appropriate to the task, and remember that you can nest layouts within the Component hierarchy.
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
{...}
}
I was drawing my game on Canvas, all was god, but I changed it into a JPanel, but now its not working correctly, here are the codes, you can just copy them and you'll see where is the problem (I have a menu and after clicking on the button it should create new thread and there i want to draw, the problem in JPanel is that the button is able to see, its blinking and i can press it, in canvas it was fine, there wasn't any button). I solved it, that after clicking on the button I setted him unvisible (button.setVisible(false)), but these codes are just examples and in my game I have more buttons, so its not practical because I need them to see after the game ends. I think I just forgot an important method in JPanel, thx for help, codes:
//Main class representing menu
public class Sandbox extends JFrame{
Panel p = new Panel();
public static void main(String[] args) {
new Sandbox();
}
public Sandbox() {
setLayout(null);
setPreferredSize(new Dimension(200, 200));
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
final JButton but = new JButton("Button");
but.setBounds(0, 0, 50, 50);
but.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
p.start();
}
});
add(p);
add(but);
pack();
setVisible(true);
}
}
//Drawing on Canvas -> working well
public class Panel extends Canvas implements Runnable {
Thread t;
public Panel() {
setSize(new Dimension(200, 200));
setVisible(false);
}
public void start() {
t = new Thread(this);
t.start();
setVisible(true);
}
public void draw() {
BufferStrategy b = getBufferStrategy();
if(b == null) {
createBufferStrategy(3);
return;
}
Graphics g = b.getDrawGraphics();
g.setColor(Color.red);
g.fillRect(0, 0, 200, 200);
g.dispose();
b.show();
}
#Override
public void run() {
while(!t.isInterrupted()) {
try {
draw();
t.sleep(200);
} catch (InterruptedException ex) {}
}
}
}
//Drawing on JPanel -> here i can press the button after first click on it
public class Panel extends JPanel implements Runnable {
Thread t;
public Panel() {
setSize(new Dimension(200, 200));
setVisible(false);
}
public void start() {
t = new Thread(this);
t.start();
setVisible(true);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(0, 0, 200, 200);
}
#Override
public void run() {
while(!t.isInterrupted()) {
try {
repaint();
t.sleep(200);
} catch (InterruptedException ex) {}
}
}
}
Not sure I understand exactly what you are trying to do but you do have a couple of problems:
the setVisible(true) method should be invoked AFTER you have added all the components to the frame and packed the frame.
by default the content pane of a JFrame uses a BorderLayout. You code is adding two components to the CENTER of the BorderLayout, but a BorderLayout only allows you to add one component to the CENTER, so only the last component added will be displayed.
I have a JPanel inside the JScrollPane and it does that whenever I try to scroll. Please help! How do I fix this?
EDIT
JScrollPane pane;
....
pane = new JScrollPane(GC.createGraph());
pane.setPreferredSize(new Dimension(480,480*2/3));
Placing as an answer for others to see. If you don't call the super.paintComponent, you'll get those artifacts. e.g.,
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.*;
public class ScrollPaneArtifacts extends JPanel {
private static final int SPA_WIDTH = 600;
private static final int SPA_HEIGHT = SPA_WIDTH;
#Override
protected void paintComponent(Graphics g) {
//super.paintComponent(g);
g.setColor(Color.red);
g.drawLine(0, 0, getWidth(), getHeight());
g.drawLine(getWidth(), 0, 0, getHeight());
}
#Override
public Dimension getPreferredSize() {
return new Dimension(SPA_WIDTH, SPA_HEIGHT);
}
private static void createAndShowUI() {
JScrollPane scrollpane = new JScrollPane(new ScrollPaneArtifacts());
scrollpane.getViewport().setPreferredSize(new Dimension(400, 400));
JFrame frame = new JFrame("ScrollPaneArtifacts");
frame.getContentPane().add(scrollpane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
You do not need to call super.paintComponent you can simply clear the area to ensure no artifacts are left on the panel from the previous render (which calling super.paintComponent will do).
#Override
protected void paintComponent(Graphics g) {
g.clearRect(0,0,getWidth(),getHeight());
g.setColor(Color.red);
g.drawLine(0, 0, getWidth(), getHeight());
g.drawLine(getWidth(), 0, 0, getHeight());
}
Try this in Hovercrafts code if you like.