I've been working on a login screen for a new project and came across a weird rendering "error" while using CardLayout on windows.
SignUp screen on Mac:SignUp Screen Mac
The screens load up correctly on my Mac computer, but on windows they look like these after you click "Register" or after you click "Back".
The same screens on windows:SignUp Screen Windows
As you can see, on windows the SignUp "card" from the CardLayout is rendered over the Login "card" without hiding the other one and vise versa, not like on mac.
Now my question is, could this be caused because of the transparent background and therefore windows thinks that the one behind should still be visible, or could it be creating a brand new "card" each time i switch, or just be forgetting to hide the one in the back all together?
Why does this work on Mac but not on Windows?
And also, how could i go about fixing this?
I will put the whole Class so you can test it for yourself.
(Side note: you may also notice that the button "Register" shows the white button shape on windows even though it has btnRegister.setBorder(null); set (works on Mac))
The complete one Class code:
package testing;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import utilities.ComponentMover;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Insets;
import javax.swing.JSeparator;
import javax.swing.JPasswordField;
#SuppressWarnings("serial")
public class ClientStarter extends JFrame implements ActionListener {
JPanel cards;
private int height = 450;
private int width = 700;
private int trasparancy = 90;
private int labelWidth = 400;
final static String BACK = "Back";
final static String REGISTER = "Register";
private Color textLine = Color.GRAY;
private Color textColor = Color.WHITE;
private Color tipColor = Color.GRAY;
private Color disabledTipColor = new Color(90, 90, 90);
// LOGIN //
JPanel loginCard;
public static JTextField usernameIn = new JTextField();
private JLabel userLabel = new JLabel("Username :");
public static JPasswordField passwordIn = new JPasswordField();
private JLabel passLabel = new JLabel("Password :");
private JButton btnLogin = new JButton("Login");
private JButton btnRegister = new JButton(REGISTER);
private JLabel registerLabel = new JLabel("Don't own an Account? ");
private JSeparator separatorUser = new JSeparator();
private JSeparator separatorPass = new JSeparator();
// SIGNUP //
JPanel joinCard;
public static JTextField emailNew = new JTextField();
public static JLabel newEmailLabel = new JLabel("Email : (Not Available)");
public static JTextField usernameNew = new JTextField();
public static JLabel newUserLabel = new JLabel("Username :");
public static JTextField passwordNew = new JTextField();
public static JLabel newPassLabel = new JLabel("Password :");
public static JTextField passwordNew2 = new JTextField();
public static JLabel newPassLabel2 = new JLabel("Re-enter password :");
private JButton btnSignUp = new JButton("Signup");
private JButton btnBack = new JButton(BACK);
private JSeparator separatorMailNew = new JSeparator();
private JSeparator separatorUserNew = new JSeparator();
private JSeparator separatorPassNew = new JSeparator();
private JSeparator separatorPassNew2 = new JSeparator();
public ClientStarter() {
getContentPane().setBackground(Color.GRAY);
setUndecorated(true);
setBackground(new Color(0, 0, 0, trasparancy));
setTitle("EnChant");
setSize(width, height);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
setResizable(false);
//Create the cards
// LOGIN //
Font avenir = new Font("Avenir", Font.PLAIN, 18);
loginCard = new JPanel();
loginCard.setLayout(null);
usernameIn.setBounds(348, 150, 327, 35);
usernameIn.setColumns(10);
usernameIn.setFont(avenir);
usernameIn.setBorder(null);
passwordIn.setBounds(348, usernameIn.getY() + 74, 327, 35);
passwordIn.setColumns(10);
passwordIn.setFont(avenir);
passwordIn.setBorder(null);
userLabel.setBounds(usernameIn.getX(), usernameIn.getY() - 20, labelWidth, 16);
userLabel.setFont(avenir);
passLabel.setBounds(passwordIn.getX(), passwordIn.getY() - 20, labelWidth, 16);
passLabel.setFont(avenir);
btnLogin.setBounds(348, passwordIn.getY() + 81, 327, 45);
btnLogin.addActionListener(this);
registerLabel.setBounds(btnLogin.getX(), btnLogin.getY() + btnLogin.getHeight() + 5, labelWidth, 16);
registerLabel.setFont(new Font("Avenir", Font.PLAIN, 13));
btnRegister.setBounds(btnLogin.getX() + 130, registerLabel.getY() - 1, 70, 16);
btnRegister.addActionListener(this);
btnRegister.setBorder(null);
loginCard.setBackground(new Color(0, 0, 0, trasparancy));
usernameIn.setBackground(new Color(0, 0, 0, 0));
usernameIn.setForeground(textColor);
passwordIn.setBackground(new Color(0, 0, 0, 0));
passwordIn.setForeground(textColor);
userLabel.setForeground(tipColor);
passLabel.setForeground(tipColor);
btnLogin.setForeground(new Color(70, 130, 180));
btnLogin.setBackground(Color.WHITE);
btnRegister.setForeground(new Color(70, 130, 180));
registerLabel.setForeground(tipColor);
separatorUser.setForeground(textLine);
separatorUser.setBounds(usernameIn.getX(), usernameIn.getY()+usernameIn.getHeight()-8, usernameIn.getWidth(), 6);
separatorPass.setForeground(textLine);
separatorPass.setBounds(passwordIn.getX(), passwordIn.getY()+passwordIn.getHeight()-8, passwordIn.getWidth(), 6);
loginCard.add(usernameIn);
loginCard.add(separatorUser);
loginCard.add(userLabel);
loginCard.add(passwordIn);
loginCard.add(separatorPass);
loginCard.add(passLabel);
loginCard.add(btnLogin);
loginCard.add(btnRegister);
loginCard.add(registerLabel);
// SIGNUP //
joinCard = new JPanel();
joinCard.setLayout(null);
emailNew.setBounds(348, 62, 327, 35);
emailNew.setColumns(10);
emailNew.setFont(avenir);
emailNew.setBorder(null);
emailNew.setEditable(false);
usernameNew.setBounds(348, emailNew.getY() + 74, 327, 35);
usernameNew.setColumns(10);
usernameNew.setFont(avenir);
usernameNew.setBorder(null);
passwordNew.setBounds(348, usernameNew.getY() + 74, 327, 35);
passwordNew.setColumns(10);
passwordNew.setFont(avenir);
passwordNew.setBorder(null);
passwordNew2.setBounds(348, passwordNew.getY() + 74, 327, 35);
passwordNew2.setColumns(10);
passwordNew2.setFont(avenir);
passwordNew2.setBorder(null);
//32, 106, 180, 254 : 2, 76, 150, 224
newEmailLabel.setBounds(emailNew.getX(), emailNew.getY() - 20, labelWidth, 16);
newEmailLabel.setFont(avenir);
newUserLabel.setBounds(usernameNew.getX(), usernameNew.getY() - 20, labelWidth, 16);
newUserLabel.setFont(avenir);
newPassLabel.setBounds(passwordNew.getX(), passwordNew.getY() - 20, labelWidth, 16);
newPassLabel.setFont(avenir);
newPassLabel2.setBounds(passwordNew2.getX(), passwordNew2.getY() - 20, labelWidth, 16);
newPassLabel2.setFont(avenir);
btnSignUp.setBounds(348, passwordNew2.getY() + 71, 327, 45); //335 // +81
btnSignUp.addActionListener(this);
btnBack.setBounds(btnSignUp.getX()-70, btnSignUp.getY(), 70, 45); //380
btnBack.addActionListener(this);
joinCard.setBackground(new Color(0, 0, 0, trasparancy));
emailNew.setBackground(new Color(0, 0, 0, 0));
emailNew.setForeground(textColor);
usernameNew.setBackground(new Color(0, 0, 0, 0));
usernameNew.setForeground(textColor);
passwordNew.setBackground(new Color(0, 0, 0, 0));
passwordNew.setForeground(textColor);
passwordNew2.setBackground(new Color(0, 0, 0, 0));
passwordNew2.setForeground(textColor);
newEmailLabel.setForeground(disabledTipColor);
newUserLabel.setForeground(tipColor);
newPassLabel.setForeground(tipColor);
newPassLabel2.setForeground(tipColor);
btnSignUp.setForeground(new Color(70, 130, 180));
btnBack.setBackground(Color.WHITE);
separatorMailNew.setBounds(emailNew.getX(), emailNew.getY()+emailNew.getHeight()-8, emailNew.getWidth(), 6);
separatorMailNew.setForeground(textLine);
separatorUserNew.setBounds(usernameNew.getX(), usernameNew.getY()+usernameNew.getHeight()-8, usernameNew.getWidth(), 6);
separatorUserNew.setForeground(textLine);
separatorPassNew.setBounds(passwordNew.getX(), passwordNew.getY()+passwordNew.getHeight()-8, passwordNew.getWidth(), 6);
separatorPassNew.setForeground(textLine);
separatorPassNew2.setBounds(passwordNew2.getX(), passwordNew2.getY()+passwordNew2.getHeight()-8, passwordNew2.getWidth(), 6);
separatorPassNew2.setForeground(textLine);
joinCard.add(emailNew);
joinCard.add(newEmailLabel);
joinCard.add(usernameNew);
joinCard.add(newUserLabel);
joinCard.add(passwordNew);
joinCard.add(newPassLabel);
joinCard.add(passwordNew2);
joinCard.add(newPassLabel2);
joinCard.add(btnSignUp);
joinCard.add(btnBack);
joinCard.add(separatorMailNew);
joinCard.add(separatorUserNew);
joinCard.add(separatorPassNew);
joinCard.add(separatorPassNew2);
// End //
JPanel whiteRectLogin = new JPanel();
whiteRectLogin.setBackground( Color.WHITE );
whiteRectLogin.setBounds(0, 0, 250, height);
loginCard.add(whiteRectLogin);
JPanel whiteRectJoin = new JPanel();
whiteRectJoin.setBackground( Color.WHITE );
whiteRectJoin.setBounds(0, 0, 250, height);
joinCard.add(whiteRectJoin);
cards = new JPanel(new CardLayout());
cards.setBackground(new Color(0, 0, 0, trasparancy));
cards.add(loginCard, BACK);
cards.add(joinCard, REGISTER);
getContentPane().add(cards);
//Top, Left, bottom, right
ComponentMover cm = new ComponentMover(this, this);
cm.setEdgeInsets(new Insets(-50, 1, 0, -50));
validate();
repaint();
getContentPane().setLayout(null);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == btnRegister) {
CardLayout cl = (CardLayout) (cards.getLayout());
cl.show(cards, REGISTER);
loginCard.setVisible(false);
}
if(e.getSource() == btnBack) {
CardLayout cl = (CardLayout) (cards.getLayout());
cl.show(cards, BACK);
loginCard.setVisible(false);
}
if(e.getSource() == btnSignUp) {
//new SignUpCheck();
}
}
public static void main(String[] args) {
new ClientStarter();
}
}
could this be caused because of the transparent background
Probably. Swing does not renderer transparent backgrounds correctly. Swing expects a component to be either fully opaque or fully transparent.
Check out Backgrounds With Transparency for a complete description of the problem and a couple of solutions.
You can either do custom painting of every component with code something like:
JPanel panel = new JPanel()
{
protected void paintComponent(Graphics g)
{
g.setColor( getBackground() );
g.fillRect(0, 0, getWidth(), getHeight());
super.paintComponent(g);
}
};
panel.setOpaque(false); // background of parent will be painted first
panel.setBackground( new Color(255, 0, 0, 20) );
frame.add(panel);
Or you can use the AlphaContainer class to do the painting for you.
Also, you have several other problems:
Don't use static variables for your Swing components. That is no the proper usage of the static keyword.
Don't use a null layout and setBounds(). Swing was designed to be used with layout managers. Layout managers work well on multiple platforms.
Don't use an alpha value of 0. The 0 means fully transparent, so just use the setOpaque(false) method on the component.
Don't keep creating new Color objects. The same Color object can be used for every component. It save resources and makes it easier to change all Color for all components all at once.
Don't use validate() and repaint() in the constructor of your class. All the components should be added to the frame BEFORE you invoke setVisible(true) so those methods are not required.
I am tring to get four side shadow effect for Tabbedpane.
My code follows like this,
MianClass
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.UIManager;
class NimbusBaseDemo extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
JTabbedPane tabbedPane;
int i;
private UIManager.LookAndFeelInfo[] lafs;
public NimbusBaseDemo() {
try {
// Set nimbus look and feel. nimbusBase works only for it.
new NimbusBaseUI();
} catch (Exception e) {
e.printStackTrace();
}
setTitle("Nimbus Base Demo");
setSize(400, 400);
setLayout(new FlowLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
tabbedPane = new JTabbedPane();
tabbedPane.addTab("World Cities", new CitiesPanel());
tabbedPane.addTab("Colors ", new ColorsPanel());
tabbedPane.addTab("World Cities", new CitiesPanel());
add(tabbedPane);
}
public static void main(String args[]) {
new NimbusBaseDemo();
}
class CitiesPanel extends JPanel {
public CitiesPanel() {
JButton b1 = new JButton("New York");
add(b1);
JButton b2 = new JButton("London");
add(b2);
JButton b3 = new JButton("Hong Kong");
add(b3);
JButton b4 = new JButton("Tokyo");
add(b4);
}
}
class ColorsPanel extends JPanel {
public ColorsPanel() {
JCheckBox cb1 = new JCheckBox("Red");
cb1.setEnabled(true);
add(cb1);
JCheckBox cb2 = new JCheckBox("Green");
cb2.setEnabled(true);
add(cb2);
JCheckBox cb3 = new JCheckBox("Blue");
add(cb3);
}
}
}
I am extending NimbusLookAndFeel class to get ride of default theme for tabbed pane. by this all my tabbed pane's in my project follows same theme.
NimbusBaseUI class
import javax.swing.UIManager;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
public class NimbusBaseUI extends NimbusLookAndFeel {
public NimbusBaseUI() {
super(); // Initialisation and installating
try {
new TabbedPaneTheme(this);
UIManager.setLookAndFeel(this);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void initialize() {
// TODO Auto-generated method stub
super.initialize();
}
}
Finally i wrote a custome theme class to apply TabbedPane. here i put tabbedpane property parameters to getdefaults() method of NimbusLookAndFeel.
TabbedPaneTheme class
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import javax.swing.Painter;
import javax.swing.plaf.ColorUIResource;
public class TabbedPaneTheme {
private Color light, dark;
private GradientPaint gradPaint;
protected int strokeSize = 1;
/** Color of shadow */
/** Color of shadow */
protected Color shadowColor = new Color(128, 128, 128, 140);
// protected Color shadowColor = new Color(0,0,0);
/** Sets if it drops shadow */
protected boolean shady = true;
/** Sets if it has an High Quality view */
protected boolean highQuality = false;
/** Double values for Horizontal and Vertical radius of corner arcs */
protected Dimension arcs = new Dimension(10, 10);
/** Distance between shadow border and opaque panel border */
protected int shadowGap = 1;
/** The offset of shadow. */
protected int shadowOffset = 1; // width of the shadow
/** The transparency value of shadow. ( 0 - 255) */
protected int shadowAlpha = 130;
public TabbedPaneTheme(NimbusBaseUI nimbusUI) {
// TODO Auto-generated constructor stub
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneTab[Enabled+Selected].shadow",
ColorUIResource.BLUE);
nimbusUI.getDefaults().put("TabbedPane:TabbedPaneTab.contentMargins",
new Insets(0, 6, 10, 6)); // (// top, left, bottom, right)
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneTabArea.contentMargins",
new Insets(0, 0, -6, 0));
nimbusUI.getDefaults().put("TabbedPane.tabAreaInsets",
new Insets(2, -1, -1, -5));
nimbusUI.getDefaults().put("TabbedPane.contentBorderInsets",
new Insets(-1, -1, -1, -5));
nimbusUI.getDefaults().put("TabbedPane.tabsOverlapBorder",
new Insets(-5, -5, -5, -5));
nimbusUI.getDefaults().put("Panel.opaque", false);
nimbusUI.getDefaults().put("TabbedPane.shadow", new Color(255, 0, 0));
nimbusUI.getDefaults().put("TabbedPane.focus", new Color(255, 0, 0));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneTab[Enabled+Selected].backgroundPainter",
new TabbedPanePainter(new Color(255, 255, 255), new Color(255,
255, 255)));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneTab[Enabled+Selected].font",
new Font("Myriad Pro", Font.BOLD, 12));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneTab[Enabled+Selected].textForeground",
new Color(91, 113, 132));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneTab[Selected].backgroundPainter",
new TabbedPanePainter(new Color(255, 255, 255), new Color(255,
255, 255)));
nimbusUI.getDefaults().put("TabbedPane:TabbedPaneTab[Selected].font",
new Font("Myriad Pro", Font.BOLD, 12));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneTab[Selected].textForeground",
new Color(91, 113, 132));
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneTab[Enabled+Selected+Pressed].backgroundPainter",
new TabbedPanePainter(new Color(255, 255, 255),
new Color(255, 255, 255)));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneTab[Enabled+Selected+Pressed].font",
new Font("Myriad Pro", Font.BOLD, 12));
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneTab[Enabled+Selected+Pressed].textForeground",
new Color(91, 113, 132));
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneTab[Default+Enabled+Selected+Pressed+Focused].backgroundPainter",
new TabbedPanePainter(new Color(255, 255, 255),
new Color(255, 255, 255)));
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneTab[Default+Enabled+Selected+Pressed+Focused].font",
new Font("Myriad Pro", Font.BOLD, 12));
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneTab[Default+Enabled+Selected+Pressed+Focused].textForeground",
new Color(91, 113, 132));
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneTab[Enabled+Selected+MouseOver].backgroundPainter",
new TabbedPanePainter(new Color(255, 255, 255),
new Color(255, 255, 255)));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneTab[Enabled+Selected+MouseOver].font",
new Font("Myriad Pro", Font.BOLD, 12));
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneTab[Enabled+Selected+MouseOver].textForeground",
new Color(91, 113, 132));
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneTab[Focused+Selected+MouseOver].backgroundPainter",
new TabbedPanePainter(new Color(255, 255, 255),
new Color(255, 255, 255)));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneTab[Focused+Selected+MouseOver].font",
new Font("Myriad Pro", Font.BOLD, 12));
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneTab[Focused+Selected+MouseOver].textForeground",
new Color(91, 113, 132));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneTab[Focused+Selected].backgroundPainter",
new TabbedPanePainter(new Color(255, 255, 255), new Color(255,
255, 255)));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneTab[Focused+Selected].font",
new Font("Myriad Pro", Font.BOLD, 12));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneTab[Focused+Selected].textForeground",
new Color(91, 113, 132));
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneTab[Enabled+Selected+MouseOver+Pressed+Focused].backgroundPainter",
new TabbedPanePainter(new Color(255, 255, 255),
new Color(255, 255, 255)));
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneTab[Enabled+Selected+MouseOver+Pressed+Focused].font",
new Font("Myriad Pro", Font.BOLD, 12));
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneTab[Enabled+Selected+MouseOver+Pressed+Focused].textForeground",
new Color(91, 113, 132));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneTab[Enabled].backgroundPainter",
new TabbedPanePainter(new Color(98, 97, 93), new Color(127,
127, 119)));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneTab[Enabled].textForeground",
new Color(255, 255, 255));
nimbusUI.getDefaults().put("TabbedPane:TabbedPaneTab[Enabled].font",
new Font("Myriad Pro", Font.BOLD, 12));
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneTab[Enabled+MouseOver].backgroundPainter",
new TabbedPanePainter(new Color(255, 255, 255),
new Color(255, 255, 255)));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneTab[Enabled+MouseOver].textForeground",
new Color(91, 113, 132));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneTab[Enabled+MouseOver].font",
new Font("Myriad Pro", Font.BOLD, 12));
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneTabArea[Enabled+MouseOver].backgroundPainter",
new TabbedPane_TabView_Painter(
new Color(255, 255, 255), new Color(255, 255,
255)));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneTabArea[Enabled].backgroundPainter",
new TabbedPane_TabView_Painter(new Color(255, 255, 255),
new Color(255, 255, 255)));
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneTabArea[Focused+Selected].backgroundPainter",
new TabbedPane_TabView_Painter(
new Color(255, 255, 255), new Color(255, 255,
255)));
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneTabArea[Focused+Selected+MouseOver].backgroundPainter",
new TabbedPane_TabView_Painter(
new Color(255, 255, 255), new Color(255, 255,
255)));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneContent.[Enabled].backgroundPainter",
new TabbedPane_TabContent_Painter(new Color(255, 255, 255),
new Color(255, 255, 255)));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneContent.[Selected].backgroundPainter",
new TabbedPane_TabContent_Painter(new Color(255, 255, 255),
new Color(255, 255, 255)));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneContent.[Focused].backgroundPainter",
new TabbedPane_TabContent_Painter(new Color(255, 255, 255),
new Color(255, 255, 255)));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneContent.[Default].backgroundPainter",
new TabbedPane_TabContent_Painter(new Color(255, 255, 255),
new Color(255, 255, 255)));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneContent.backgroundPainter",
new TabbedPane_TabContent_Painter(Color.WHITE, Color.WHITE));
nimbusUI.getDefaults().put("TabbedPane:TabbedPaneContent.background",
Color.WHITE);
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneContent.[Enabled+MouseOver].backgroundPainter",
new TabbedPane_TabContent_Painter(new Color(255, 255,
255), new Color(255, 255, 255)));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneContent.[Selected].backgroundPainter",
new TabbedPane_TabContent_Painter(new Color(255, 255, 255),
new Color(255, 255, 255)));
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneContent.[Enabled+Selected].backgroundPainter",
new TabbedPane_TabContent_Painter(new Color(255, 255,
255), new Color(255, 255, 255)));
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneContent.[Enabled+Focused].backgroundPainter",
new TabbedPane_TabContent_Painter(new Color(255, 255,
255), new Color(255, 255, 255)));
nimbusUI.getDefaults().put(
"TabbedPane:TabbedPaneContent.[Selected].backgroundPainter",
new TabbedPane_TabContent_Painter(new Color(255, 255, 255),
new Color(255, 255, 255)));
nimbusUI.getDefaults()
.put("TabbedPane:TabbedPaneContent.[Enabled+Pressed].backgroundPainter",
new TabbedPane_TabContent_Painter(new Color(255, 255,
255), new Color(255, 255, 255)));
}
public class TabbedPane_TabContent_Painter implements Painter {
private Color light, dark;
private GradientPaint gradPaint;
public TabbedPane_TabContent_Painter(Color light, Color dark) {
this.light = light;
this.dark = dark;
}
#Override
public void paint(Graphics2D g, Object c, int w, int h) {
Color shadowColorA = new Color(shadowColor.getRed(),
shadowColor.getGreen(), shadowColor.getBlue(), shadowAlpha);
if (highQuality) {
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
if (shady) {
g.setColor(shadowColorA);
g.fillRoundRect(0, 0, w - shadowGap, h - shadowGap, arcs.width,
arcs.height);
} else {
shadowGap = 1;
}
gradPaint = new GradientPaint((w / 2.0f), 0, new Color(255, 255,
255), (w / 2.0f), (h / 2.0f), new Color(255, 255, 255),
false);
g.setPaint(gradPaint);
g.fillRoundRect(shadowOffset,// X position
shadowOffset,// Y position
w - strokeSize - shadowOffset, // width
h - strokeSize - shadowOffset, // height
arcs.width, arcs.height);// arc Dimension
g.setColor(new Color(188, 188, 187, 130));
g.setStroke(new BasicStroke(strokeSize));
g.drawRoundRect(shadowOffset,// X position
shadowOffset,// Y position
w - strokeSize - shadowOffset, // width
h - strokeSize - shadowOffset, // height
arcs.width, arcs.height);// arc Dimension
g.setStroke(new BasicStroke());
}
}
public class TabbedPane_TabView_Painter implements Painter {
private Color light, dark;
private GradientPaint gradPaint;
public TabbedPane_TabView_Painter(Color light, Color dark) {
this.light = light;
this.dark = dark;
}
#Override
public void paint(Graphics2D g, Object c, int w, int h) {
Color shadowColor = Color.black;
Color shadowColorA = new Color(shadowColor.getRed(),
shadowColor.getGreen(), shadowColor.getBlue(), 150);
g.setColor(shadowColorA);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
gradPaint = new GradientPaint((w / 2.0f), 0, light, (w / 2.0f),
(h / 2.0f), dark, true);
g.setPaint(gradPaint);
}
}
public class TabbedPanePainter implements Painter {
private Color light, dark;
private GradientPaint gradPaint;
public TabbedPanePainter(Color light, Color dark) {
this.light = light;
this.dark = dark;
}
#Override
public void paint(Graphics2D g, Object c, int w, int h) {
Color shadowColor = Color.black;
Color shadowColorA = new Color(shadowColor.getRed(),
shadowColor.getGreen(), shadowColor.getBlue(), 150);
g.setColor(shadowColorA);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
gradPaint = new GradientPaint((w / 2.0f), 0, light, (w / 2.0f),
(h / 2.0f), dark, true);
g.setPaint(gradPaint);
// g.fillRect(2, 2, (w - 5), (h - 5));
g.fillRoundRect(2, 2, (w - 5), (h - 5), 6, 6);
}
}
}
I got results like
But i want to acchive shadow effect four sides of tabbedpane and shadow for selected tabbedpane TAB also.
Like this
Appetiate your help & suggestions.
To get better help sooner:
Check this out: Nimbus Defaults (The Java™ Tutorials > Creating a GUI With JFC/Swing > Modifying the Look and Feel) and remove unnecessary keys from the TabbedPaneTheme class, e.g. TabbedPane:...font, TabbedPane:TabbedPaneContent.[Enabled+Pressed]...
Remove unrelated code: Color light, dark;, CitiesPanel, ColorsPanel class, NimbusBaseUI#initialize() method, ...
TabbedPane_TabView_Painter is not do anything.
Here's my attempt:
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
public class NimbusTabbedPaneTest {
public JComponent makeUI() {
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.addTab("World Cities", new JScrollPane(new JTree()));
tabbedPane.addTab("Colors ", new JSplitPane());
tabbedPane.addTab("World Cities", new JScrollPane(new JTextArea()));
tabbedPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
return tabbedPane;
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
try {
new NimbusBaseUI();
} catch (Exception e) {
e.printStackTrace();
}
JFrame f = new JFrame("Nimbus Base Demo");
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new NimbusTabbedPaneTest().makeUI());
f.setSize(400, 400);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
class NimbusBaseUI extends NimbusLookAndFeel {
public NimbusBaseUI() {
super();
try {
new TabbedPaneTheme(this);
UIManager.setLookAndFeel(this);
} catch (Exception e) {
e.printStackTrace();
}
}
}
class TabbedPaneTheme {
protected static int OVERPAINT = 6;
protected static int shadowOffset = 1;
protected static int strokeSize = 2;
protected static Dimension arcs = new Dimension(10, 10);
public TabbedPaneTheme(NimbusBaseUI nimbusUI) {
UIDefaults d = nimbusUI.getDefaults();
d.put("TabbedPane:TabbedPaneContent.contentMargins", new Insets(0, 5, 5, 5));
//d.put("TabbedPane:TabbedPaneTab.contentMargins", new Insets(2, 8, 3, 8));
//d.put("TabbedPane:TabbedPaneTabArea.contentMargins", new Insets(3, 10, 4, 10));
d.put("TabbedPane:TabbedPaneTabArea.contentMargins",
new Insets(3, 10, OVERPAINT, 10));
Painter<JComponent> tabAreaPainter = new TabAreaPainter();
d.put("TabbedPane:TabbedPaneTabArea[Disabled].backgroundPainter",
tabAreaPainter);
d.put("TabbedPane:TabbedPaneTabArea[Enabled].backgroundPainter",
tabAreaPainter);
d.put("TabbedPane:TabbedPaneTabArea[Enabled+MouseOver].backgroundPainter",
tabAreaPainter);
d.put("TabbedPane:TabbedPaneTabArea[Enabled+Pressed].backgroundPainter",
tabAreaPainter);
d.put("TabbedPane:TabbedPaneContent.backgroundPainter",
new TabContentPainter());
Painter<JComponent> tabPainter = new TabPainter(Color.ORANGE, false);
d.put("TabbedPane:TabbedPaneTab[Enabled+MouseOver].backgroundPainter",
tabPainter);
d.put("TabbedPane:TabbedPaneTab[Enabled+Pressed].backgroundPainter",
tabPainter);
d.put("TabbedPane:TabbedPaneTab[Enabled].backgroundPainter",
tabPainter);
Painter<JComponent> selectedTabPainter = new TabPainter(Color.WHITE, true);
d.put("TabbedPane:TabbedPaneTab[Focused+MouseOver+Selected].backgroundPainter",
selectedTabPainter);
d.put("TabbedPane:TabbedPaneTab[Focused+Pressed+Selected].backgroundPainter",
selectedTabPainter);
d.put("TabbedPane:TabbedPaneTab[Focused+Selected].backgroundPainter",
selectedTabPainter);
d.put("TabbedPane:TabbedPaneTab[MouseOver+Selected].backgroundPainter",
selectedTabPainter);
d.put("TabbedPane:TabbedPaneTab[Selected].backgroundPainter",
selectedTabPainter);
d.put("TabbedPane:TabbedPaneTab[Pressed+Selected].backgroundPainter",
selectedTabPainter);
}
private static class TabPainter implements Painter<JComponent> {
private final Color color;
private int r = 6;
private int x = 3;
private int y = 3;
private boolean selected;
public TabPainter(Color color, boolean selected) {
this.color = color;
this.selected = selected;
}
#Override public void paint(Graphics2D g, JComponent c, int width, int height) {
int ex = selected ? OVERPAINT : 0;
Graphics2D g2 = (Graphics2D) g.create(0, 0, width, height + ex);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int w = width - 6 - 1;
int h = height + r;
for (int i = 0; i < 3; i++) {
g2.setColor(new Color(0, 0, 0, 20));
g2.fill(new RoundRectangle2D.Double(x - i, y - i, w + i + i, h, r, r));
}
g2.setColor(color);
g2.fill(new RoundRectangle2D.Double(x, y, w, h + 4, r, r));
g2.dispose();
}
}
private static class TabAreaPainter implements Painter<JComponent> {
#Override public void paint(Graphics2D g, JComponent c, int w, int h) {
Graphics2D g2 = (Graphics2D) g.create(0, 0, w, h);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
RoundRectangle2D r = new RoundRectangle2D.Double(
shadowOffset,// X position
shadowOffset + h - OVERPAINT,// Y position
w - strokeSize - shadowOffset, // width
40, // height
arcs.width, arcs.height);// arc Dimension
g2.setPaint(Color.CYAN);
g2.fill(r);
g2.setColor(Color.RED);
g2.setStroke(new BasicStroke(strokeSize));
g2.draw(r);
g2.dispose();
}
}
private static class TabContentPainter implements Painter<JComponent> {
#Override public void paint(Graphics2D g, JComponent c, int w, int h) {
Graphics2D g2 = (Graphics2D) g.create(0, 0, w, h);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.translate(0, -OVERPAINT);
h += OVERPAINT;
RoundRectangle2D r = new RoundRectangle2D.Double(
shadowOffset,// X position
shadowOffset,// Y position
w - strokeSize - shadowOffset, // width
h - strokeSize - shadowOffset, // height
arcs.width, arcs.height);// arc Dimension
g2.setPaint(Color.WHITE);
g2.fill(r);
g2.setColor(Color.ORANGE);
g2.setStroke(new BasicStroke(strokeSize));
g2.draw(r);
g2.dispose();
}
}
}
Hi I've got a problem in the code below ( in method "append(String str)" mostly). I want to show messages received in HTML format (so I need to use JLabel).
Without setting tac.preferredSize here is what I get:
BUT it isn't working using long string without blank spaces:
such as "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".
If I set tac.preferredSize the height of the bubble isn't increasing:
How can I overcome these problems? (working on layout/sizes and not modifying input string)
Here's the code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ClientGUI extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
private JLabel label;
private JTextField tf;
private JPanel chatPanel;
private JScrollPane scroll;
ClientGUI() {
super("Chat Client");
label = new JLabel("You can write messages below:", SwingConstants.CENTER);
chatPanel = new JPanel();
tf = new JTextField("");
tf.setBackground(Color.WHITE);
tf.requestFocus();
tf.setVisible(true);
tf.addActionListener(this);
chatPanel.setLayout(new BoxLayout(chatPanel, BoxLayout.PAGE_AXIS));
chatPanel.add(Box.createVerticalGlue());
JPanel centerPanel = new JPanel(new GridLayout(1,1));
scroll = new JScrollPane();
scroll.setViewportView(chatPanel);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
centerPanel.add(scroll);
add(centerPanel, BorderLayout.CENTER);
JPanel southPanel = new JPanel(new BorderLayout());
JPanel writeChatPanel = new JPanel(new GridLayout(2,1));
writeChatPanel.add(label);
writeChatPanel.add(tf);
southPanel.add(writeChatPanel, BorderLayout.NORTH);
add(southPanel, BorderLayout.SOUTH);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(600, 600);
setVisible(true);
chatPanel.scrollRectToVisible(new Rectangle(chatPanel.getSize()));
}
void append(String str) {
LeftArrowBubble leftArrowBubble = new LeftArrowBubble();
leftArrowBubble.setMaximumSize(new Dimension(400,350));
JLabel tac = new JLabel();
tac.setMaximumSize(new Dimension(350,400));
//tac.setPreferredSize(new Dimension(350,50)); //<----------
System.out.println(str);
tac.setText("<html><body style='width: 350px; padding:15px;display:block;'>"+str+"</body></html>");
tac.setOpaque(false);
leftArrowBubble.add(tac, BorderLayout.NORTH);
chatPanel.add(leftArrowBubble);
chatPanel.add(Box.createRigidArea(new Dimension(0,5)));
Rectangle rect = chatPanel.getBounds();
Rectangle r2 = scroll.getViewport().getVisibleRect();
chatPanel.scrollRectToVisible(new Rectangle((int) rect.getWidth(),
(int) rect.getHeight(), (int) r2.getWidth(), (int) r2.getHeight()));
revalidate();
repaint();
}
public void actionPerformed(ActionEvent e) {
// just have to send the message
append(tf.getText());
tf.setText("");
return;
}
public static void main(String[] args) {
new ClientGUI();
}
}
And the bubble class:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.GeneralPath;
import javax.swing.BoxLayout;
import javax.swing.JPanel;
public class LeftArrowBubble extends JPanel {
private static final long serialVersionUID = -5389178141802153305L;
public LeftArrowBubble() {
this.setLayout(new BoxLayout(this,BoxLayout.PAGE_AXIS));
}
#Override
protected void paintComponent(final Graphics g) {
final Graphics2D graphics2D = (Graphics2D) g;
RenderingHints qualityHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
qualityHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
graphics2D.setRenderingHints(qualityHints);
graphics2D.setPaint(new Color(80, 150, 180));
int width = getWidth();
int height = getHeight();
GeneralPath path = new GeneralPath();
path.moveTo(5, 10);
path.curveTo(5, 10, 7, 5, 0, 0);
path.curveTo(0, 0, 12, 0, 12, 5);
path.curveTo(12, 5, 12, 0, 20, 0);
path.lineTo(width - 10, 0);
path.curveTo(width - 10, 0, width, 0, width, 10);
path.lineTo(width, height - 10);
path.curveTo(width, height - 10, width, height, width - 10, height);
path.lineTo(15, height);
path.curveTo(15, height, 5, height, 5, height - 10);
path.lineTo(5, 15);
path.closePath();
graphics2D.fill(path);
}
}
If you break up the words that are too long by adding spaces, I think most of your problems are solved. Some small changes to the dimensions of the leftArrowBubble and tac components would be useful as well.
You could replace the following lines in the append method:
leftArrowBubble.setMaximumSize(new Dimension(400,350));
JLabel tac = new JLabel();
tac.setMaximumSize(new Dimension(350,400));
//tac.setPreferredSize(new Dimension(350,50)); //<----------
System.out.println(str);
tac.setText("<html><body style='width:350px;padding:15px;display:block;'>"
+ str + "</body></html>");
by the following code (you can also take a look at Split string to equal length substrings in Java for more ways to split a string in equal parts):
leftArrowBubble.setMaximumSize(new Dimension(500, 500));
JLabel tac = new JLabel();
tac.setMaximumSize(new Dimension(450, 450));
//tac.setPreferredSize(new Dimension(350, 50)); //<----------
final int maximumSize = 56;
String textWithSeparators = "";
final StringTokenizer textTokenizer
= new StringTokenizer(str, " \t\n\r", true);
while (textTokenizer.hasMoreTokens()) {
final String part = textTokenizer.nextToken();
for (int beginIndex = 0; beginIndex < part.length();
beginIndex += maximumSize)
textWithSeparators += (beginIndex == 0 ? "" : " ")
+ part.substring(beginIndex,
Math.min(part.length(),
beginIndex + maximumSize));
}
System.out.println(textWithSeparators);
tac.setText("<html><body style='width:350px;padding:15px;display:block;'>"
+ textWithSeparators + "</body></html>");
The value for maximumSize could be calculated using font metrics (see How to get the correct String width from FontMetrics in JAVA for more information), but I've used a fixed value here for the sake of simplicity.
It would be nice to link the dimensions of leftArrowBubble, tac, and the width in the html string, like:
final int size = 500;
leftArrowBubble.setMaximumSize(new Dimension(size, size));
JLabel tac = new JLabel();
tac.setMaximumSize(new Dimension(size - 50, size - 50));
// [...]
tac.setText("<html><body style='width:" + (size - 150)
+ "px;padding:15px;display:block;'>"
+ textWithSeparators + "</body></html>");
So, I'm trying to make a program where you can input the quadratic formula (ax^2+bx+c) via sliders. Then it draws a graph as you adjust for A, B, and C.
Issues:
I want the stuff I wrote in super paint and the sliders to be in one place.
The sliders are in place when I run it. There's space with the correct background where I want my graph in the panel but no actual graph.
Here's my driver class:
import java.awt.*;
import javax.swing.*;
public class quadraticslider
{
public static void main (String[] args)
{
JFrame frame = new JFrame ("Quadratic Slider");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new pp109quadraticpanel());
frame.pack();
frame.setVisible(true);
}
}
Here's the panel class:
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
public class quadraticpanel extends JPanel
{
private JPanel controls, graphPanel;
private JSlider ASlider, BSlider, CSlider;
private JLabel ALabel, BLabel, CLabel;
double A, B, C, x,Y;
//
//SLIDERS YO
//
public quadraticpanel()
{
ASlider = new JSlider (JSlider.HORIZONTAL, 0, 255, 0);
ASlider.setMajorTickSpacing (50);
ASlider.setMinorTickSpacing (10);
ASlider.setPaintTicks (true);
ASlider.setPaintLabels (true);
ASlider.setAlignmentX (Component.LEFT_ALIGNMENT);
BSlider = new JSlider (JSlider.HORIZONTAL, 0, 255, 0);
BSlider.setMajorTickSpacing (50);
BSlider.setMinorTickSpacing (10);
BSlider.setPaintTicks (true);
BSlider.setPaintLabels (true);
BSlider.setAlignmentX (Component.LEFT_ALIGNMENT);
CSlider = new JSlider (JSlider.HORIZONTAL, 0, 255, 0);
CSlider.setMajorTickSpacing (50);
CSlider.setMinorTickSpacing (10);
CSlider.setPaintTicks (true);
CSlider.setPaintLabels (true);
CSlider.setAlignmentX (Component.LEFT_ALIGNMENT);
SliderListener listener = new SliderListener();
ASlider.addChangeListener (listener);
BSlider.addChangeListener (listener);
CSlider.addChangeListener (listener);
ALabel = new JLabel ("a: 0");
ALabel.setAlignmentX (Component.LEFT_ALIGNMENT);
BLabel = new JLabel ("b: 0");
BLabel.setAlignmentX (Component.LEFT_ALIGNMENT);
CLabel = new JLabel ("c: 0");
CLabel.setAlignmentX (Component.LEFT_ALIGNMENT);
controls = new JPanel();
BoxLayout layout = new BoxLayout (controls, BoxLayout.Y_AXIS);
controls.setLayout (layout);
controls.add (ALabel);
controls.add (ASlider);
controls.add (Box.createRigidArea (new Dimension (0, 20)));
controls.add (BLabel);
controls.add (BSlider);
controls.add (Box.createRigidArea (new Dimension (0, 20)));
controls.add (CLabel);
controls.add (CSlider);
graphPanel = new JPanel();
graphPanel.setPreferredSize (new Dimension (500, 500));
graphPanel.setBackground (Color.white);
add (controls);
add (graphPanel);
}
//Here I'm taking the equation, running it through -10 to 10
//It takes the doubles from the equation, converts
//it to int then draws the quadratic formula in dots.
public void paintComponent(Graphics page)
{
super.paintComponent (page);
for ( x=-10; x <= 10; x++)
{
Y = (A*(Math.pow(x,2)))+(B*x)+(C);
int g = (int)Math.round(x);
int h = (int)Math.round(Y);
page.setColor (Color.black);
page.fillOval (g, h, 1, 1);
}
}
public class SliderListener implements ChangeListener
{
///
///Reads the user input via slider.
///
public void stateChanged (ChangeEvent event)
{
A = ASlider.getValue();
B = BSlider.getValue();
C = CSlider.getValue();
ALabel.setText ("a: " + A);
BLabel.setText ("b: " + B);
CLabel.setText ("c: " + C);
}
}
}
These examples using JFreeChart may be of interest. As shown here, you can animate the rendering using SwingWorker, and this example updates a chart using a JSlider.
Addendum: This variation of your code may guide you going forward. Note,
Override relevant methods in your graphPanel.
Scale and invert coordinates, as shown here.
Consider JSpinner for fractional values.
Use constants for consistency.
Use common naming conventions for clarity.
See also Initial Threads.
import java.awt.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/** #see https://stackoverflow.com/a/20556929/230513 */
public class QuadraticSlider {
private static final int N = 500;
private static final int A = 1;
private static final int B = 0;
private static final int C = 0;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Quadratic Slider");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new QuadraticPanel());
frame.pack();
frame.setVisible(true);
}
});
}
private static class QuadraticPanel extends JPanel {
private Box controls;
private JPanel graphPanel;
private JSlider aSlider, bSlider, cSlider;
private JLabel aLabel, bLabel, cLabel;
double a, b, c, x, y;
public QuadraticPanel() {
aSlider = new JSlider(JSlider.HORIZONTAL, -25, 25, A);
aSlider.setMajorTickSpacing(10);
aSlider.setMinorTickSpacing(5);
aSlider.setPaintTicks(true);
aSlider.setPaintLabels(true);
aSlider.setAlignmentX(Component.LEFT_ALIGNMENT);
bSlider = new JSlider(JSlider.HORIZONTAL, -10, 10, B);
bSlider.setMajorTickSpacing(5);
bSlider.setMinorTickSpacing(1);
bSlider.setPaintTicks(true);
bSlider.setPaintLabels(true);
bSlider.setAlignmentX(Component.LEFT_ALIGNMENT);
cSlider = new JSlider(JSlider.HORIZONTAL, -100, 100, C);
cSlider.setMajorTickSpacing(50);
cSlider.setMinorTickSpacing(10);
cSlider.setPaintTicks(true);
cSlider.setPaintLabels(true);
cSlider.setAlignmentX(Component.LEFT_ALIGNMENT);
SliderListener listener = new SliderListener();
aSlider.addChangeListener(listener);
bSlider.addChangeListener(listener);
cSlider.addChangeListener(listener);
aLabel = new JLabel("a: 0");
bLabel = new JLabel("b: 0");
cLabel = new JLabel("c: 0");
controls = new Box(BoxLayout.Y_AXIS);
controls.add(aLabel);
controls.add(aSlider);
controls.add(Box.createRigidArea(new Dimension(0, 20)));
controls.add(bLabel);
controls.add(bSlider);
controls.add(Box.createRigidArea(new Dimension(0, 20)));
controls.add(cLabel);
controls.add(cSlider);
graphPanel = new JPanel() {
private static final int SCALE = 5;
#Override
public Dimension getPreferredSize() {
return new Dimension(N, N);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (x = -10; x <= 10; x++) {
y = a * x * x + b * x + c;
g.setColor(Color.black);
int w = (int) (x * SCALE) + N / 2;
int h = (int) (-y * SCALE) + N / 2;
g.fillOval(w, h, 5, 5);
}
}
};
graphPanel.setBackground(Color.white);
add(controls);
add(graphPanel);
listener.stateChanged(null);
}
class SliderListener implements ChangeListener {
#Override
public void stateChanged(ChangeEvent event) {
a = aSlider.getValue() / 5d;
b = bSlider.getValue();
c = cSlider.getValue();
aLabel.setText("a: " + a);
bLabel.setText("b: " + b);
cLabel.setText("c: " + c);
repaint();
}
}
}
}
_"error: possible loss of precision Y = (A*(Math.pow(x,2)))+(B*x)+(C); ^ required: int found: double"_
All your int variables int A, B, C, x,Y;. Make them doubles. double A, B, C, x,Y;
I modified the code so that it solves for x given a b and c. Then plugs x back in and solves for y. I'm still not getting it to draw though. I also took out the loop since the sliders are setting the a b and c values which lead to x. Anyone know why it won't draw?
package quadraticslider;
import java.awt.*;
import javax.swing.*;
public class quadraticslider
{
public static void main (String[] args)
{
JFrame frame = new JFrame ("Quadratic Slider");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new quadraticpanel());
frame.pack();
frame.setVisible(true);
}
}
package quadraticslider;
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
public class quadraticpanel extends JPanel
{
private JPanel controls, graphPanel;
private JSlider ASlider, BSlider, CSlider;
private JLabel ALabel, BLabel, CLabel;
double A, B, C, x,Y;
public quadraticpanel()
{
ASlider = new JSlider (JSlider.HORIZONTAL, -25, 25, 0);
ASlider.setMajorTickSpacing (50);
ASlider.setMinorTickSpacing (10);
ASlider.setPaintTicks (true);
ASlider.setPaintLabels (true);
ASlider.setAlignmentX (Component.LEFT_ALIGNMENT);
BSlider = new JSlider (JSlider.HORIZONTAL, -25, 25, 0);
BSlider.setMajorTickSpacing (50);
BSlider.setMinorTickSpacing (10);
BSlider.setPaintTicks (true);
BSlider.setPaintLabels (true);
BSlider.setAlignmentX (Component.LEFT_ALIGNMENT);
CSlider = new JSlider (JSlider.HORIZONTAL, -25, 25, 0);
CSlider.setMajorTickSpacing (50);
CSlider.setMinorTickSpacing (10);
CSlider.setPaintTicks (true);
CSlider.setPaintLabels (true);
CSlider.setAlignmentX (Component.LEFT_ALIGNMENT);
SliderListener listener = new SliderListener();
ASlider.addChangeListener (listener);
BSlider.addChangeListener (listener);
CSlider.addChangeListener (listener);
ALabel = new JLabel ("a: 0");
ALabel.setAlignmentX (Component.LEFT_ALIGNMENT);
BLabel = new JLabel ("b: 0");
BLabel.setAlignmentX (Component.LEFT_ALIGNMENT);
CLabel = new JLabel ("c: 0");
CLabel.setAlignmentX (Component.LEFT_ALIGNMENT);
controls = new JPanel();
BoxLayout layout = new BoxLayout (controls, BoxLayout.Y_AXIS);
controls.setLayout (layout);
controls.add (ALabel);
controls.add (ASlider);
controls.add (Box.createRigidArea (new Dimension (0, 20)));
controls.add (BLabel);
controls.add (BSlider);
controls.add (Box.createRigidArea (new Dimension (0, 20)));
controls.add (CLabel);
controls.add (CSlider);
graphPanel = new JPanel();
graphPanel.setPreferredSize (new Dimension (500, 500));
graphPanel.setBackground (Color.white);
add (controls);
add (graphPanel);
}
public void paintComponent(Graphics page)
{
super.paintComponent (page);
x = (-B + (Math.sqrt((B*B - ((4 * A * C))))))/ (2 * A);
Y = (A*(Math.pow(x,2)))+(B*x)+(C);
int g = (int)Math.round(x);
int h = (int)Math.round(Y);
page.setColor (Color.black);
page.drawOval (g, h, 1, 1);
}
public class SliderListener implements ChangeListener
{
///
///Reads the user input via slider.
///
public void stateChanged (ChangeEvent event)
{
A = ASlider.getValue();
B = BSlider.getValue();
C = CSlider.getValue();
ALabel.setText ("a: " + A);
BLabel.setText ("b: " + B);
CLabel.setText ("c: " + C);
}
}
}