Change tab look for JTabbedpane - java

How can I remove OR change colour of the border surrounding these tabs?
ALSO, is it possible to have the tab text change colour when the mouse is hovering over it?

Is it possible to have the tab text change colour when the mouse is
hovering over it?
As stated in this answer you can set a custom component for rendering the tab title, through JTabbedPane.setTabComponentAt(int index, Component component) method. So you can do something like this:
final JTabbedPane tabbedPane = new JTabbedPane();
MouseListener mouseListener = new MouseAdapter() {
Color defaultColor;
#Override
public void mouseEntered(MouseEvent e) {
JLabel label = (JLabel)e.getSource();
defaultColor = label.getForeground();
label.setForeground(Color.BLUE);
}
#Override
public void mouseExited(MouseEvent e) {
JLabel label = (JLabel)e.getSource();
label.setForeground(defaultColor);
}
#Override
public void mouseClicked(MouseEvent e) {
JLabel label = (JLabel)e.getSource();
Point point = SwingUtilities.convertPoint(label, e.getPoint(), tabbedPane);
int selectedTab = tabbedPane.getUI().tabForCoordinate(tabbedPane, point.x, point.y);
switch(e.getButton()){
case MouseEvent.BUTTON2: tabbedPane.removeTabAt(selectedTab); break;
default: tabbedPane.setSelectedIndex(selectedTab);
}
}
};
JLabel tab1 = new JLabel("Tab1");
tab1.addMouseListener(mouseListener);
tabbedPane.addTab(null, new JPanel());
tabbedPane.setTabComponentAt(0, tab1);
How can I remove OR change colour of the border surrounding these
tabs?
It's up to the Look and Feel decide the border color in this case. You should look into the L&F default properties and see if it's allowed change this color. For instance you could execute the following code to see L&F default properties (of course after setting the L&F):
for(Object key : UIManager.getLookAndFeelDefaults().keySet()){
System.out.println(key + " = " + UIManager.get(key));
}

Related

How to change JLabel background when I click the JLabel in Java

I want to change my JLabel background to blue using mouseClicked. The name of my JLabel is lblKembali. I tried this code and when I tried to click the label it didnt change the background. Please help. Thank you.
lblKembali = new JLabel("Kembali");
lblKembali.setPreferredSize(new Dimension(400,30));
lblKembali.setMaximumSize(getPreferredSize());
lblKembali.addMouseListener(new java.awt.event.MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
lblKembali.setBackground(Color.BLUE);
}
});
By default a JLabel is non-opaque so its background is not painted. You need to make the label opaque when you create it:
lblKembali = new JLabel("Kembali");
lblKembali.setOpaque( true );
Also you can make your listener more generic so it can be shared by multiple components by doing:
public void mouseClicked(MouseEvent e)
{
Component c = e.getComponent();
c.setBackground(Color.BLUE);
}

JLabel translation

I have a JLabel (with an icon) and I would like to translate this JLabel when the JLabel is clicked. I have added a mouseListener to the JLabel however I didn't come up with anything on how I can execute a translation from coordinates (x, y) to cordinates (x', y')
class MyMouseListener extends MouseAdapter {
#Override
public void mouseClicked(MouseEvent e){
final JLabel label = (JLabel) e.getSource();
System.out.println("Player hit label -> " + label.getName() );
// Code for translating JLabel
}
}
As far as translating (ie moving) your JLabel:
First, you must make sure that the layout manager of its parent is set to null, or uses a customized layoutmanager that can be configured to do your translation.
Once you have that in place, it's a simple matter:
public void mouseClicked(MouseEvent ae) {
JLabel src = (JLabel) ae.getSource();
src.setLocation(src.getLocation().x + delta_x, src.getLocation().y + delta_y);
src.getParent().repaint();
}

Seems like JPanel background isn't read in FocusListener

This problem appeared after my last question here. I want to set each button focused and lost focus background to background color which is below main menu (ContentPane which is JPanel), so buttons look like tabs. It couuld be different in different environments, so it is dynamic, so I can't set it manually. Now, If I log ContentPane background it says 238, 238, 238. If I log it inside FocusListener - it also states 238, 238, 238. If I directly set button's background to ContentPane background outside FocusListener - it works, but if I set inside FocusListener - it looks like value is not read and set, but if I set color manually - it works. How this could happen? Setting FocusListener to buttons is the last thing what I do in initialization of main JPanel.
private void setButtonDefaults(JButton but) {//calls once for each menu button to set defaults
but.setBorderPainted(false);
but.setBackground(Color.DARK_GRAY);
but.setForeground(Color.WHITE);
but.setName(but.getText().toLowerCase());
but.setPreferredSize(buttonSize);
but.addActionListener(this);
//add focus listener
but.addFocusListener(new FocusListener() {
#Override
public void focusLost(FocusEvent e) {
Color clr = ContentPane.getBackground();
log(clr + "");//logs that color is 238, 238, 238
JButton button = (JButton) e.getSource();
button.setBackground(clr);//value is not read
//button.setBackground(new Color(238, 238, 238)); //value is read
}
#Override
public void focusGained(FocusEvent e) {
//same as focusLost function
}
});
}
private void enableOnlyOne(JButton but) {
/* calls each time when one of menu buttons are pressed.
All buttons are unpressed and changed colors to black and one
button is set as pressed and changes background color to
ContentPane background color
*/
//disable all
setButtonDisabled(MLibrary);
setButtonDisabled(MScheduler);
setButtonDisabled(MBudget);
setButtonDisabled(MReports);
setButtonDisabled(MManage);
setButtonDisabled(MSettings);
//enable one
but.getModel().setPressed(true);
but.setBackground(ContentPane.getBackground());//value is read perfect
but.setForeground(Color.BLACK);
}
private void setButtonDisabled(JButton but) {
but.getModel().setPressed(false);
but.setBackground(Color.DARK_GRAY);
but.setForeground(Color.WHITE);
}
please don't do that this way, since I read your previous thread ..., now I can't resist
better and easiest way is add ChangeListener to expected JButtons, then inside stateChanged(ChangeEvent changeEvent) you can determine which of JButtons fired this event, for type of event you have to extract this event's type from ButtonModel
(rest is up to you, please put these JButtons to the Vector, Array or Enumerations), for example
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
public class MyButtonGroup {
private JButton button1 = new JButton("Test Enabled / Disabled");
private JButton button2 = new JButton("Test Enabled / Disabled");
private JButton button3 = new JButton("Test Enabled / Disabled");
public MyButtonGroup() {
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3, 0, 10, 10));
button1.addChangeListener(changeListener);
panel.add(button1);
button2.addChangeListener(changeListener);
panel.add(button2);
button3.addChangeListener(changeListener);
panel.add(button3);
JFrame frame = new JFrame("Grouping Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
private ChangeListener changeListener = new ChangeListener() {
public void stateChanged(ChangeEvent changeEvent) {
JButton abstractButton = (JButton) changeEvent.getSource();
if (abstractButton == button1) {
ButtonModel buttonModel = abstractButton.getModel();
boolean armed = buttonModel.isArmed();
boolean pressed = buttonModel.isPressed();
boolean selected = buttonModel.isSelected();
boolean rolover = buttonModel.isRollover();
System.out.println("Changed: " + armed + "/" + pressed + "/" + selected + "/" + rolover);
} else if (abstractButton == button2) {
ButtonModel buttonModel = abstractButton.getModel();
boolean armed = buttonModel.isArmed();
boolean pressed = buttonModel.isPressed();
boolean selected = buttonModel.isSelected();
boolean rolover = buttonModel.isRollover();
System.out.println("Changed: " + armed + "/" + pressed + "/" + selected + "/" + rolover);
}
}
};
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MyButtonGroup xxx = new MyButtonGroup();
}
});
}
}
Because some L&Fs don't display changes to the background color is a useful way, you may want to consider another form of highlighting: a different border, an altered foreground color, a custom icon, or a suitable background panel. More here.
It is so good to find out answer by myself:
private void setButtonDefaults(JButton but) {
but.setBorderPainted(false);
but.setBackground(Color.DARK_GRAY);
but.setForeground(Color.WHITE);
but.setName(but.getText().toLowerCase());
but.setPreferredSize(buttonSize);
but.addActionListener(this);
//add focus listener
final Color clr = ContentPane.getBackground();
final int r = clr.getRed();
final int g = clr.getGreen();
final int b = clr.getBlue();
but.addFocusListener(new FocusListener() {
#Override
public void focusLost(FocusEvent e) {
log("r = " + r + ", g = " + g + ", b = " + b);
JButton button = (JButton) e.getSource();
button.setBackground(new Color(r, g, b));
}
#Override
public void focusGained(FocusEvent e) {
JButton button = (JButton) e.getSource();
button.setBackground(new Color(r, g, b));
}
});
}
Thanks to everyone who tried (and did) to help me

Swing : Setting JButton's background

I want to set the background color of JButton. For that I use
setBackground() method.
This method jsut sets the border color of the button and not the whole button of the specified color. Why so ? This is the only method to set background color of a button. Where am I making a mistake due to which it sets just the border of the button of specified color and not actual button ?
Code :
account_btn.setAction(actionMap.get("AccountingClicked")); // NOI18N
account_btn.setBackground(Utility.getBackgroundColor());
account_btn.setFont(Utility.getButtonFont());
account_btn.setForeground(Utility.getTextColor());
org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(cashaccountingapp.CashAccountingApp.class).getContext().getResourceMap(MainPanel.class);
account_btn.setText(resourceMap.getString("account_btn.text")); // NOI18N
account_btn.setBorderPainted(false);
account_btn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
account_btn.setName("account_btn"); // NOI18N
account_btn.setOpaque(true);
add(account_btn);
Result :
Have tried setting setOpaque(true) also. But you can see the results of account_btn i.e. "Accounting". setOpaque seems to have no effects.
Any idea.
SOLUTION :
Setting L&F
private void initLookandFeel() {
try {
System.out.println("DEFAULT Look & Feel = " + UIManager.getLookAndFeelDefaults().toString());
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
javax.swing.SwingUtilities.updateComponentTreeUI(this.mainPanel);
System.out.println("Look & Feel = " + UIManager.getLookAndFeel().toString());
} catch(Exception e) { ..... }
}
I call initLookandFeel() after initComponents() and also update my mainPanel. Also needed to update my dynamically added panel at initial stage then no need to set anything more.
import java.awt.*;
import javax.swing.*;
class ColoredButtons {
ColoredButtons() {
JPanel gui = new JPanel(new GridLayout(1,0,5,5));
JButton one = new JButton("One");
one.setBackground(Color.RED);
JButton two = new JButton("Two");
two.setBackground(Color.RED);
gui.add(one);
gui.add(two);
JOptionPane.showMessageDialog(null, gui);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ColoredButtons();
}
});
}
}
There is my SSCCE. The buttons are red. The PLAF is metal.
Which brings me back to: Where is your SSCCE? What PLAF are you using?
I believe the Jbutton background is controlled by the particular look-and-feel you are using. To change the background you may need to modify the
setUI(ComponentUI newUI)
with your own one.
Try setting border painted to false and opaque true
account_btn.setBorderPainted(false);
account_btn.setOpaque(true);

MouseEvents for a JTabbedPane Tab component are not bleeding through

I have a JTabbedPane with a custom tab component. That component contains a JLabel (To display the tab title) and a JButton (A close button). When I change the text in the JLabel the JLabel stops receiving mouse events and I can no longer select that tab when I click directly on the label instead if I click around the label then I can select the tab. Any ideas?
A snippet of the code:
class ShellPanelTabComponent extends JPanel implements ActionListener{
private ShellPanel panel;
private JLabel label;
public ShellPanelTabComponent(final ShellPanel panel){
super(new FlowLayout(FlowLayout.LEFT, 0, 0));
this.panel = panel;
setOpaque(false);
label = new JLabel(panel.getTitle());
label.setFocusable(false);
add(label);
label.setBorder(BorderFactory.createEmptyBorder(2,0,0,5));
//now the button
CloseButton closeButton = new CloseButton(panel);
add(closeButton);
closeButton.addActionListener(this);
}
public void actionPerformed(ActionEvent ae) {
panel.getShell().removeShellPanel(panel);
}
/**
* #return the label
*/
public JLabel getLabel() {
return label;
}
}
I don't recall seeing such a problem in the TabComponentsDemo, discussed in How to Use Tabbed Panes. You might compare your code with that example as a reference.
Addendum: Re-factoring ButtonTabComponent to include getLabel(), this version of runTest() in TabComponentsDemo adds a button that evinces the desired behavior. In particular, each time the button is pressed, the tabs are redrawn to display the enlarged title.
Update: Modify correct tab component after pane.remove().
public void runTest() {
pane.removeAll();
for (int i = 0; i < tabNumber; i++) {
final int titleIndex = i;
String title = "Tab " + titleIndex;
final JButton button = new JButton("Relabel tab");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int index = pane.indexOfComponent(button);
ButtonTabComponent btc = (ButtonTabComponent)
pane.getTabComponentAt(index);
JLabel label = btc.getLabel();
pane.setTitleAt(index, label.getText() + titleIndex);
label.invalidate();
pane.repaint();
}
});
pane.add(title, button);
initTabComponent(i);
}
tabComponentsItem.setSelected(true);
pane.setTabLayoutPolicy(JTabbedPane.WRAP_TAB_LAYOUT);
scrollLayoutItem.setSelected(false);
this.setPreferredSize(new Dimension(500, 200));
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
I seem to remember a question like this recently although I can't find the posting. I believe the problem is that the "custom component" receives the mouse event so it is not passed on to the tabbed pane. The solution suggested was to use the dispatchEvent(...) method to redispatch the mouse event to the proper tab.
The problem is related to the one that I posted here after I did more digging: Workaround for setToolTipText consuming mouse events?

Categories