How to hide the knob of jSlider? - java

I need to customize the knob of JSlider. I need to put my own knob's image over default knob of Jslider.
The problem is that currently two knobs are coming in response. One my own knob and second the default knob. Please tell me how i can i hide the default knob or any other solution.
Below code is used to do so.
public class ImageTest {
JSlider slider;
JLabel label;
public ImageTest()
{
JPanel panel = new BackgroundPanel();
slider = new BackgroundSlider();
slider.setMaximum(300);
slider.setMinimum(0);
slider.setValue(50);
slider.setExtent(10);
slider.addChangeListener(new MyChangeAction());
label = new JLabel("50");
panel.setLayout(new GridBagLayout());
panel.setSize(797,402);
slider.setOpaque(false);
slider.setPaintTrack(false);
label.setOpaque(false);
slider.setPreferredSize(new Dimension(340, 20));
GridBagConstraints gridBagConstraintsSlider = new GridBagConstraints();
gridBagConstraintsSlider.gridy = 0;
gridBagConstraintsSlider.gridx = 0;
gridBagConstraintsSlider.fill = GridBagConstraints.HORIZONTAL;
gridBagConstraintsSlider.insets = new Insets(0, 283, 260, 0);
GridBagConstraints gridBagConstraints = new GridBagConstraints();
gridBagConstraints.gridy = 0;
gridBagConstraints.gridx = 1;
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
gridBagConstraints.insets = new Insets(0, 50, 240, 0);
panel.add(slider, gridBagConstraintsSlider);
panel.add(label, gridBagConstraints);
JFrame frame = new JFrame();
frame.getContentPane().add(panel);
frame.setSize(797,402);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
WindowUtil.locateCenter(frame);
}
public static void main(String[] args) {
ImageTest im= new ImageTest();
}
public class MyChangeAction implements ChangeListener{
public void stateChanged(ChangeEvent ce){
int value = slider.getValue();
String str = Integer.toString(value);
label.setText(str);
if(value==300)
{
label.setText("Max");
}
}
}
}
class BackgroundSlider extends JSlider
{
Image image;
public BackgroundSlider()
{
try
{
image = javax.imageio.ImageIO.read(new File("slider.png"));
}
catch (Exception e) { /*handled in paintComponent()*/ }
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
if (image != null)
g.drawImage(image, this.getValue(),(int)this.getAlignmentY(),10,20,this);
g.setColor(Color.RED);
//draw a centered horizontal line
g.drawRect(15,this.getHeight()-1,this.getValue(),this.getHeight()+2);
g.fillRect(15,this.getHeight()-1,this.getValue(),this.getHeight()+2);
}
}
Thanks
Jyoti

To hide the knob, override the UIManager's Slider.horizontalThumbIcon property with an blank icon, like this:
public static void main(String[] args) throws Exception {
UIManager.getLookAndFeelDefaults().put("Slider.horizontalThumbIcon",new Icon(){
#Override
public int getIconHeight() {
return 0;
}
#Override
public int getIconWidth() {
return 0;
}
#Override
public void paintIcon(Component c, Graphics g, int x, int y) {
//do nothing
}
});
JFrame f = new JFrame();
JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, 30, 15);
slider.setMajorTickSpacing(10);
slider.setMinorTickSpacing(1);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
f.add(slider);
f.setSize(200,200);
f.setVisible(true);
}

A solution with a different BasicSliderUI looks like this:
public class SuperSlider extends JSlider {
public SuperSlider(int min, int max, int value) {
super(min,max,value);
setUI(new SuperSliderUI(this));
}
private class SuperSliderUI extends BasicSliderUI {
#Override
public void paintThumb(Graphics g) {
}
}
}

The UIManager solution only works in the Metal LAF from what I can tell.
If you want to change the behavour of the UI then you need to change the UI. In this case you would need to the BasicSliderUI (or one of its sub classes). Then I believe you would need to override the paintThumb() method.

Related

ActionListener to draw shapes on separate panel

I want my GUI to draw circles/rectangles on the exact position I coded in the method paintComponent when I click on the respective buttons.
But I just don't know how to go on. What should I tell actionPerformed to do? Trying for a few hours to figure out a way, but I'm only getting errors.
public class Kreise extends JFrame {
Kreise() {
setLayout(new GridLayout(2, 1));
JLabel label = new JLabel("Draw Circ / Rect here: ");
label.setLayout(new FlowLayout(FlowLayout.CENTER));
JPanel jp1 = new JPanel();
jp1.setBackground(Color.LIGHT_GRAY);;
jp1.add(label);
JPanel jp2 = new JPanel(new FlowLayout());
JButton circ = new JButton("Circle");
JButton rect = new JButton("Rectangle");
circ.addActionListener(new KRListener(true));
rect.addActionListener(new KRListener(false));
jp2.add(circ);
jp2.add(rect);
MyPanel obj = new MyPanel();
jp1.add(obj);
add(jp1);
add(jp2);
setSize(400, 250);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public class MyPanel extends JPanel {
public boolean circleZ = true;
public void paintComponent(Graphics g) {
if (circleZ = true) {
super.paintComponent(g);
g.drawOval(150, 50, 50, 50);
} else if (circleZ = false) {
super.paintComponent(g);
g.drawRect(150, 50, 50, 50);
}
}
}
public class KRListener implements ActionListener {
boolean b;
KRListener(boolean b) {
this.b = b;
}
public void actionPerformed(ActionEvent e) {
?
}
}
public static void main(String[] args) {
new Kreise();
}
}
Presuming I understand the question clearly (you wish to toggle between the a rectangle or circle), in the ActionListener implementation you need to:
Toggle the appropriate boolean value
Call repaint on the JPanel instance that performs the painting
One way to accomplish these steps is to have a single toggle JButton, and pass an instance of the JPanel used for drawing to your ActionListener implementation, which can be used to accomplish both steps above:
public class KRListener implements ActionListener {
private MyPanel panel;
KRListener(MyPanel panel) {
this.panel = panel;
}
#Override
public void actionPerformed(ActionEvent e) {
panel.circleZ = !panel.circleZ;
panel.repaint();
}
}
And when you paint:
if ( circleZ ){
g.drawOval(150, 50, 50, 50);
}else{
g.drawRect(150, 50, 50, 50);
}
I dont know what you are using the global boolean variable b for But I noticed that you have to call the repaint() method when you press the Button.
public class KRListener implements ActionListener {
boolean b;
KRListener(boolean b) {
this.b = b;
}
#Override
public void actionPerformed(ActionEvent e){
//add some code here to change properties of the drawing before calling the repaint method?
repaint();
}
}

JScrollPane not showing scrollbars when an Array of JPanels are added to it

Im adding an array of JPanels inside a JScrollPane. The array of JPanels are being added to the JScrollPane but the scroll bars just wont show.
public class MyFrame extends JFrame {
private JPanel contentPane;
private JPanel panel_1;
private JScrollPane scrollPane;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MyFrame frame = new MyFrame();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public MyFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 288, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
panel_1 = new JPanel();
panel_1.setBounds(10, 114, 434, 136);
panel_1.setLayout(null);
scrollPane = new JScrollPane(panel_1);
scrollPane.setBounds(52, 57, 164, 126);
scrollPane.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Histogram", TitledBorder.LEADING, TitledBorder.TOP, null, Color.BLUE));
scrollPane.setLayout(new ScrollPaneLayout());
contentPane.add(scrollPane);
buildBar();
}
JPanel[] barPanel;
private void buildBar(){
int x=0,y=22,w=100,h=80,s=10,n=3;
barPanel = new JPanel[n];
for(int i=0; i<n; i++){
barPanel[i] = new JPanel();
barPanel[i].setBounds(x, y, w, h);
barPanel[i].setBackground(new Color(255,0,0));
panel_1.add(barPanel[i]);
panel_1.revalidate();
panel_1.repaint();
x = x + w + s;
}
}
}
I have been working on it for hours . Maybe there is something that I've missed out.
You're shooting yourself in the foot with these two lines:
panel_1.setBounds(10, 114, 434, 136);
panel_1.setLayout(null);
Both of which will mess up the JScrollPane's ability to use and display scrollbars. What you need to do is: not to use setBounds but rather have the components use their preferredSize, and avoid using null layout, since this won't change the container's preferredSize.
Yet another reason to studiously avoid null layouts.
e.g.,
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.*;
public class MyPanel2 extends JPanel {
private static final int PREF_W = 388;
private static final int PREF_H = PREF_W;
public static final int INNER_PREF_W = 434;
public static final int INNER_PREF_H = 126;
private static final int HISTO_PANEL_COUNT = 6;
private static final Dimension VP_SZ = new Dimension(164, 126);
private JPanel holderPanel = new JPanel(new GridLayout(0, 1));
public MyPanel2() {
int w = INNER_PREF_W;
int h = INNER_PREF_H;
for (int i = 0; i < HISTO_PANEL_COUNT; i++) {
holderPanel.add(new InnerPanel(w, h));
}
JScrollPane scrollPane = new JScrollPane(holderPanel);
scrollPane.getViewport().setPreferredSize(VP_SZ);
setLayout(new GridBagLayout());
add(scrollPane);
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class InnerPanel extends JPanel {
private int w;
private int h;
public InnerPanel(int w, int h) {
this.w = w;
this.h = h;
setBorder(BorderFactory.createLineBorder(Color.BLUE));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int x = 0, y = 22, w = 100, h = 80, s = 10, n = 3;
g.setColor(Color.RED);
for (int i = 0; i < n; i++) {
g.fillRect(x, y, w, h);
x = x + w + s;
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(w, h);
}
}
private static void createAndShowGui() {
MyPanel2 mainPanel = new MyPanel2();
JFrame frame = new JFrame("MyPanel2");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
JScrollPane relies on the preferredSize of your container to determine the scroll bar width. If you use a Layout, the preferredSize will be determined for you when components are added to the panel.
However, when you use:
contentPane.setLayout(null);
You are preventing the preferredSize from changing based on added components.
Try to use a layout which is applicable for your case.
In case you are very certain you do not want to use a Layout, in order to see the scroll bar, you may set the preferredSize of the container for every components you added by manually adjusting the preferredSize. That way, the scrollbar will still extend with newly added components.

Moving JPasswordField to absolute position

I have this code:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class DialogExample extends JPanel {
private static final int COLUMN_COUNT = 10;
private static final int I_GAP = 3;
public static final String BKG_IMG_PATH = "http://upload.wikimedia.org/wikipedia/commons/"
+ "thumb/9/92/Camels_in_Jordan_valley_%284568207363%29.jpg/800px-Camels_in_Jordan_valley_"
+ "%284568207363%29.jpg";
private BufferedImage backgrndImage;
private JTextField userNameField = new JTextField();
private JPasswordField passwordField = new JPasswordField();
private JPanel mainPanel = new JPanel(new GridBagLayout());
private JButton okButton = new JButton("OK");
private JButton cancelButton = new JButton("Cancel");
public DialogExample(BufferedImage backgrndImage) {
this.backgrndImage = backgrndImage;
userNameField.setColumns(COLUMN_COUNT);
passwordField.setColumns(COLUMN_COUNT);
JPanel btnPanel = new JPanel(new GridLayout(1, 0, 5, 5));
btnPanel.setOpaque(false);
btnPanel.add(okButton);
btnPanel.add(cancelButton);
GridBagConstraints gbc = getGbc(0, 0, GridBagConstraints.BOTH);
mainPanel.add(createLabel("User Name", Color.white), gbc);
gbc = getGbc(1, 0, GridBagConstraints.HORIZONTAL);
mainPanel.add(userNameField, gbc);
gbc = getGbc(0, 1, GridBagConstraints.BOTH);
mainPanel.add(createLabel("Password:", Color.white), gbc);
gbc = getGbc(1, 1, GridBagConstraints.HORIZONTAL);
mainPanel.add(passwordField, gbc);
gbc = getGbc(0, 2, GridBagConstraints.BOTH, 2, 1);
mainPanel.add(btnPanel, gbc);
mainPanel.setOpaque(false);
add(mainPanel);
}
private JLabel createLabel(String text, Color color) {
JLabel label = new JLabel(text);
label.setForeground(color);
return label;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (backgrndImage != null) {
g.drawImage(backgrndImage, 0, 0, this);
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet() || backgrndImage == null) {
return super.getPreferredSize();
}
int imgW = backgrndImage.getWidth();
int imgH = backgrndImage.getHeight();
return new Dimension(imgW, imgH);
}
public static GridBagConstraints getGbc(int x, int y, int fill) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.insets = new Insets(I_GAP, I_GAP, I_GAP, I_GAP);
gbc.fill = fill;
return gbc;
}
public static GridBagConstraints getGbc(int x, int y, int fill, int width,
int height) {
GridBagConstraints gbc = getGbc(x, y, fill);
gbc.gridwidth = width;
gbc.gridheight = height;
return gbc;
}
private static void createAndShowGui() throws IOException {
final JFrame frame = new JFrame("Frame");
final JDialog dialog = new JDialog(frame, "User Sign-In", ModalityType.APPLICATION_MODAL);
URL imgUrl = new URL(BKG_IMG_PATH);
BufferedImage img = ImageIO.read(imgUrl);
final DialogExample dlgExample = new DialogExample(img);
dialog.add(dlgExample);
dialog.pack();
JPanel mainPanel = new JPanel();
mainPanel.add(new JButton(new AbstractAction("Please Press Me!") {
#Override
public void actionPerformed(ActionEvent e) {
dialog.setVisible(true);
}
}));
mainPanel.setPreferredSize(new Dimension(800, 650));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
createAndShowGui();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
Ho can I move the JPasswordField to a absolute position (X,Y)?? I've been trying different things like setPosition(int X, int Y) and nothing worked. I tryed playing too with the layout but not success either. I would like to have just a JPasswordField object and a button object on his right. that's it
Thank you
Start by creating a panel for the password field and button to reside on. Next, randomise a EmptyBorder and the Insets of a GridBagConstraints to define different locations within the parent container. Add the password/button panel to this container with these randomised constraints...
public class TestPane extends JPanel {
public TestPane() {
Random rnd = new Random();
JPanel panel = new JPanel();
JPasswordField pf = new JPasswordField(10);
JButton btn = new JButton("Login");
panel.add(pf);
panel.add(btn);
panel.setBorder(new EmptyBorder(rnd.nextInt(10), rnd.nextInt(10), rnd.nextInt(10), rnd.nextInt(10)));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(rnd.nextInt(100), rnd.nextInt(100), rnd.nextInt(100), rnd.nextInt(100));
add(panel, gbc);
}
}
The other choice would be to write your own custom layout manager...but if you can avoid it, the above example is MUCH simpler...
ps- You could randomise either the border OR the insets, maybe using a larger random range and get the same effect, I've simpler used both to demonstrate the point ;)
Updated with layout manager example
public class TestPane extends BackgroundImagePane {
public TestPane() throws IOException {
super(ImageIO.read(new File("Path/to/your/image")));
Random rnd = new Random();
JPanel panel = new JPanel();
panel.setOpaque(false);
JPasswordField pf = new JPasswordField(10);
JButton btn = new JButton("Login");
panel.add(pf);
panel.add(btn);
setLayout(new RandomLayoutManager());
Dimension size = getPreferredSize();
size.width -= panel.getPreferredSize().width;
size.height -= panel.getPreferredSize().height;
add(panel, new Point(rnd.nextInt(size.width), rnd.nextInt(size.height)));
}
}
public class RandomLayoutManager implements LayoutManager2 {
private Map<Component, Point> mapConstraints;
public RandomLayoutManager() {
mapConstraints = new WeakHashMap<>(25);
}
#Override
public void addLayoutComponent(String name, Component comp) {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public void removeLayoutComponent(Component comp) {
mapConstraints.remove(comp);
}
#Override
public Dimension preferredLayoutSize(Container parent) {
Area area = new Area();
for (Component comp : mapConstraints.keySet()) {
Point p = mapConstraints.get(comp);
Rectangle bounds = new Rectangle(p, comp.getPreferredSize());
area.add(new Area(bounds));
}
Rectangle bounds = area.getBounds();
Dimension size = bounds.getSize();
size.width += bounds.x;
size.height += bounds.y;
return size;
}
#Override
public Dimension minimumLayoutSize(Container parent) {
return preferredLayoutSize(parent);
}
#Override
public void layoutContainer(Container parent) {
for (Component comp : mapConstraints.keySet()) {
Point p = mapConstraints.get(comp);
comp.setLocation(p);
comp.setSize(comp.getPreferredSize());
}
}
#Override
public void addLayoutComponent(Component comp, Object constraints) {
if (constraints instanceof Point) {
mapConstraints.put(comp, (Point) constraints);
} else {
throw new IllegalArgumentException("cannot add to layout: constraint must be a java.awt.Point");
}
}
#Override
public Dimension maximumLayoutSize(Container target) {
return preferredLayoutSize(target);
}
#Override
public float getLayoutAlignmentX(Container target) {
return 0.5f;
}
#Override
public float getLayoutAlignmentY(Container target) {
return 0.5f;
}
#Override
public void invalidateLayout(Container target) {
}
}
public class BackgroundImagePane extends JPanel {
private Image image;
public BackgroundImagePane(Image img) {
this.image = img;
}
#Override
public Dimension getPreferredSize() {
return image == null ? super.getPreferredSize() : new Dimension(image.getWidth(this), image.getHeight(this));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
int x = (getWidth() - image.getWidth(this)) / 2;
int y = (getHeight() - image.getHeight(this)) / 2;
g.drawImage(image, x, y, this);
}
}
}
The BackgroundImagePane is based on this example, allowing the background image panel to be the container for the field panel and you should be well on your way...
You could use a null layout, but that takes too long and it doesn't re-size with the frame.
Like this:
public class TestPane{
public static void main (String[] args) {
Random rnd = new Random();
JFrame frame = new JFrame();
JPasswordField pf = new JPasswordField();
JButton btn = new JButton("Login");
frame.setSize(500, 500);
frame.setLayout(null);
btn.setBounds(y, x, width, height);
pf.setBounds(y, x, width, height);
frame.add(btn);
frame.add(pf);
}
}
And that should work.
If you want to use a null layout.

drawing in swing Java

I'm making the game "Who is millionaire".
This is the help panel, which let user choose one of the options such as: calling friend, asking audience, etc.
But I have a problem, the options are ellipses, which are drawn in class Help_Option extends JComponent. When I test this class Help_Option individually, it works fine. But when I add the Help_Option object into the game panel, actually a sub-panel in the frame, it just displays a line on the panel, it doesn't draw my ellipse.
This is my code:
Note: a is JFrame, I don't copy the whole method initialize(JFrame a) cos it's quite long and I don't think that the error comes from there.
/******Helper panel**********/
JPanel help_area_container = new JPanel();
help_area_container.setBorder(BorderFactory.createLineBorder(Color.BLUE, 3));
help_area_container.setLayout(new GridLayout(4,0));
JPanel voting_container = new JPanel();
JPanel calling_container = new JPanel();
JPanel half_container = new JPanel();
JPanel take_container = new JPanel();
JPanel[] all_help_container = new JPanel[]{voting_container, calling_container, half_container, take_container};
for(int i = 0; i < all_help_container.length; i++){
all_help_container[i].setBorder(BorderFactory.createLineBorder(Color.RED));
all_help_container[i].setPreferredSize(new Dimension(350, help_area_container.getPreferredSize().height/4));
}
for(int j = 0; j < all_help_container.length; j++){
help_area_container.add(all_help_container[j]);
}
Help_Option voting_option = new Help_Option(all_help_container[0].getPreferredSize().width, all_help_container[0].getPreferredSize().height);
voting_option.setPreferredSize(new Dimension(all_help_container[0].getPreferredSize().width, all_help_container[0].getPreferredSize().height));
all_help_container[0].add(voting_option);
a.add(help_area_container, BorderLayout.EAST);
/*****************************/
This is the Help_Option class:
class Help_Option extends JComponent implements MouseMotionListener{
private static int x, y;
private Ellipse2D ellipse;
private Color c = Color.BLACK;
public Help_Option(int x, int y){
Help_Option.x = x;
Help_Option.y = y;
ellipse = new Ellipse2D.Double(0, 0, x, y);
this.addMouseMotionListener(this);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLUE);
g2d.draw(ellipse);
g2d.setColor(c);
g2d.fill(ellipse);
g2d.setColor(Color.RED);
g2d.setFont(new Font("TimesRoman", Font.BOLD, 20));
g2d.drawString("Here I am", 250, 100);
}
public void setColor(Color c){
this.c = c;
}
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
if(ellipse.contains(e.getX(), e.getY())){
setColor(Color.GREEN);
repaint();
}else{
setColor(Color.BLACK);
repaint();
}
}
}
And this is the class that i used to test Help_Option class:
public class Help extends JFrame{
public static void main(String [] agrs){
Help h = new Help();
h.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
h.init();
}
public void init(){
this.setLayout(new FlowLayout());
this.setSize(2000, 1000);
JPanel a = new JPanel();
a.setPreferredSize(new Dimension((int)a.getSize().width/3, (int)a.getSize().height/2));
a.setBorder(BorderFactory.createLineBorder(Color.yellow, 3));
Help_Option k = new Help_Option(a.getPreferredSize().width, a.getPreferredSize().height/2);
k.setPreferredSize(new Dimension(a.getPreferredSize().width, a.getPreferredSize().height));
a.add(k);
this.add(a);
this.setVisible(true);
}
}
EDIT
This is the link to my classes, please take a look at them. The error is described above.
It is that you haven't set values for your first couple of JPanels and they are returning preferred sizes of 0. Dimensions of 0,0
So you should add values to the JPanels there.
public static void main(String[] args) {
JPanel help_area_container = new JPanel();
help_area_container.setBorder(BorderFactory.createLineBorder(
Color.BLUE, 3));
help_area_container.setLayout(new GridLayout(4, 0));
//Should have set sizes below
JPanel voting_container = new JPanel();
//voting_container.setSize(50,50);
JPanel calling_container = new JPanel();
JPanel half_container = new JPanel();
JPanel take_container = new JPanel();
JPanel[] all_help_container = new JPanel[] { voting_container,
calling_container, half_container, take_container };
for (int i = 0; i < all_help_container.length; i++) {
all_help_container[i].setBorder(BorderFactory
.createLineBorder(Color.RED));
all_help_container[i].setPreferredSize(new Dimension(350,
help_area_container.getPreferredSize().height / 4));
}
for (int i = 0; i < all_help_container.length; i++) {
System.out.println(all_help_container[i].getSize());
}
}
// where you can change the size
all_help_container[0].setSize(50, 50);
System.out.println("----");
for (int i = 0; i < all_help_container.length; i++) {
System.out.println(all_help_container[i].getSize());
}
}
Hopefully this will help you with the sizing of your GUI.
You will have to adjust the different panels to suit your needs. As I'm guessing that this panels will contain some other stuff in them.
You may want to create custom JPanels for each of these, so that you can easily check if they are the right size.
public class VotingPanel extends JPanel {
public VotingPanel(){
//All your variables such as size and color schemes
}
}

How to add close button to a JTabbedPane Tab?

I'm working in with a JTabbedPane, I need to add a close button in the tabs to close the current one.
I have been searching and as I understand I must extend from JPanel and add the close button as they say here
But, is there a way to add the close buttons extending JTabbedPane or is there a easier way to do it?
Thanks in advance, I really appreciate your time and your help.
Essentially, you're going to need to supply a "renderer" for the tab. Take a look at JTabbedPane.setTabComponentAt(...) for more information.
The basic idea is to supply a component that will be laid out on the tab.
I typically create a JPanel, onto which I add a JLabel (for the title) and, depending on what I want to display, some kind of control that acts as the close action.
tabPane.addTab(title, tabBody);
int index = tabPane.indexOfTab(title);
JPanel pnlTab = new JPanel(new GridBagLayout());
pnlTab.setOpaque(false);
JLabel lblTitle = new JLabel(title);
JButton btnClose = new JButton("x");
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
pnlTab.add(lblTitle, gbc);
gbc.gridx++;
gbc.weightx = 0;
pnlTab.add(btnClose, gbc);
tabPane.setTabComponentAt(index, pnlTab);
btnClose.addActionListener(myCloseActionHandler);
Now somewhere else, I establish the action handler...
public class MyCloseActionHandler implements ActionListener {
public void actionPerformed(ActionEvent evt) {
Component selected = tabPane.getSelectedComponent();
if (selected != null) {
tabPane.remove(selected);
// It would probably be worthwhile getting the source
// casting it back to a JButton and removing
// the action handler reference ;)
}
}
}
Now, you just as easily use any component you like and attach a mouse listener to it and monitor the mouse clicks...
Updated
The above example will only remove the currently active tab, there are a couple of ways to fix this.
The best is to probably provide some means for the action to find the tab it's associated with...
public class MyCloseActionHandler implements ActionListener {
private String tabName;
public MyCloseActionHandler(String tabName) {
this.tabName = tabName;
}
public String getTabName() {
return tabName;
}
public void actionPerformed(ActionEvent evt) {
int index = tabPane.indexOfTab(getTabName());
if (index >= 0) {
tabPane.removeTabAt(index);
// It would probably be worthwhile getting the source
// casting it back to a JButton and removing
// the action handler reference ;)
}
}
}
This uses the name of tab (as used with JTabbedPane#addTab) to find and then remove the tab and its associated component...
I found a tab example (from the java site) that appears to do that, at least in theirs. (Though I thought, when I tried it in the past, that it also closed the currently selected tab, though it works properly when you run their example, though I think when I updated it to work on a tabbed java notepad, it was closing the currently selected tab, though maybe I did it wrong.
http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/uiswing/examples/components/TabComponentsDemoProject/src/components/ButtonTabComponent.java
Yes, my thing is working now! This WILL work for the actual tab, rather than the currently selected tab!
Hopefully you have got the answer to your question. I want to give a link that was very useful for me.
JTabbedPane with a close button
Here is some code as well.
public static void createAndShowGUI()
{
JFrame frame = new JFrame("Tabs");
frame.setMinimumSize(new Dimension(500, 200));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTabbedPane tabbedPane = new JTabbedPane();
JPanel panel = new JPanel();
panel.setOpaque(false);
tabbedPane.add(panel);
tabbedPane.setTabComponentAt(tabbedPane.indexOfComponent(panel), getTitlePanel(tabbedPane, panel, "Tab1"));
JPanel panel1 = new JPanel();
panel1.setOpaque(false);
tabbedPane.add(panel1);
tabbedPane.setTabComponentAt(tabbedPane.indexOfComponent(panel1), getTitlePanel(tabbedPane, panel1, "Tab2"));
JPanel panel2 = new JPanel();
panel2.setOpaque(false);
tabbedPane.add(panel2);
tabbedPane.setTabComponentAt(tabbedPane.indexOfComponent(panel2), getTitlePanel(tabbedPane, panel2, "Tab3"));
JPanel panel3 = new JPanel();
panel3.setOpaque(false);
tabbedPane.add(panel3);
tabbedPane.setTabComponentAt(tabbedPane.indexOfComponent(panel3), getTitlePanel(tabbedPane, panel3, "Tab4"));
frame.add(tabbedPane);
// Display the window.
frame.pack();
frame.setVisible(true);
}
I made some changes in the code of oracle.
http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/uiswing/examples/components/TabComponentsDemoProject/src/components/ButtonTabComponent.java
Giving the possibility to add an icon to the tab , plus the close tab button. Hope that helps.
public static void addTag(JTabbedPane tab, String title, Icon icon, int index){
MouseListener close = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
//your code to remove component
//I use this way , because I use other methods of control than normal: tab.remove(int index);
}
};
final ButtonClose buttonClose = new ButtonClose (title, icon, close );
tab.setTabComponentAt(index, buttonClose);
tab.validate();
tab.setSelectedIndex(index);
}
public class ButtonClose extends JPanel {
public ButtonClose(final String title, Icon icon, MouseListener e) {
JLabel ic = new JLabel(icon);
ic.setSize(icone.getIconWidth(), icone.getIconHeight());
JLabel text= new JLabel(title);
text.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
ButtonTab button = new ButtonTab();
button.addMouseListener(e);
button.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
JPanel p = new JPanel();
p.setSize(getWidth() - icone.getIconWidth(), 15);
p.add(text);
p.add(button);
add(ic);
add(p);
}
private class ButtonTab extends JButton {
public ButtonTab() {
int size = 13;
setPreferredSize(new Dimension(size, size));
setToolTipText("Close");
setUI(new BasicButtonUI());
setFocusable(false);
setBorderPainted(false);
addMouseListener(listener);
setRolloverEnabled(true);
}
#Override
public void updateUI() {
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
if (getModel().isPressed()) {
g2.translate(1, 1);
}
g2.setStroke(new BasicStroke(2));
g2.setColor(new Color(126, 118, 91));
if (getModel().isRollover()) {
g2.setColor(Color.WHITE);
}
int delta = 3;
g2.drawLine(delta, delta, getWidth() - delta - 1, getHeight() - delta - 1);
g2.drawLine(getWidth() - delta - 1, delta, delta, getHeight() - delta - 1);
g2.dispose();
}
}
private final MouseListener listener = new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
Component component = e.getComponent();
if (component instanceof AbstractButton) {
AbstractButton button = (AbstractButton) component;
button.setContentAreaFilled(true);
button.setBackground(new Color(215, 65, 35));
}
}
#Override
public void mouseExited(MouseEvent e) {
Component component = e.getComponent();
if (component instanceof AbstractButton) {
AbstractButton button = (AbstractButton) component;
button.setContentAreaFilled(false); //transparent
}
}
};
}
Check out Peter-Swing here. It has a JClosableTabbedPane class in it, as well as many others.
When you download the jar file you can run it and have examples of all the classes.
You can have a JLabel named "x" and use the mouseListener
private final JLabel l = new JLabel(); // this is the label for tabbedPane
private final JLabel b = new JLabel("x");//Close Button
if (closeable)
{
b.setToolTipText("Click to close");
b.setOpaque(false);
b.setBackground(Color.gray);
b.addMouseListener(new MouseAdapter()
{
#Override
public void mouseExited(MouseEvent e)
{
b.setBorder(bordere);
b.setOpaque(false);
}
#Override
public void mouseEntered(MouseEvent e)
{
b.setBorder(borderl);
}
#Override
public void mouseReleased(MouseEvent e)
{
b.setOpaque(false);
b.repaint();
if (b.contains(e.getPoint()))
{
b.setBorder(borderl);
if (confirmTabClosing())
{
tab.remove(tabIndex());
if(tab.getTabCount() == 0)
spacialTabComponent.maximizeOrRestore.doClick();
}
}
else
b.setBorder(bordere);
}
#Override
public void mousePressed(MouseEvent e)
{
b.setOpaque(true);
b.repaint();
}
});
b.setBorder(bordere);
add(b, getLeftAlignedBothFilledGBC(1, 0, new Insets(0, 0, 0, 0), 0, 0));
}
}
jbCloseButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int index = jtbMainTabbedPane.indexOfTabComponent(jbCloseButton);
jtbMainTabbedPane.remove(index);
}
});

Categories