I've started adding a few buttons to my new Java Swing project (first time using Swing) and I tried adding a mouse listener event to them with the intention of having the background of the (transparent) button to change to a darker color when the mouse is hovering over it.
I did this using JPanels behind the the buttons, and I tried changing their backgrounds to a 50% opaque color.
Code:
for(int i=0;i<5;i++){
JPanel p = new JPanel();
p.setOpaque(false);
b[i].setContentAreaFilled(false); //b is an array consisting of 5 buttons
b[i].setForeground(Color.RED); //
b[i].addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
p.setOpaque(true);
p.setBackground(new Color(0,0,0,50));
}
public void mouseExited(MouseEvent e){
p.setOpaque(false);
p.setBackground(new Color(0,0,0,0));
}
p.add(b[i]);
}
I have multiple unexpected things happen with this code:
Every time I click the button (I have no ActionListener on them) the button (and only the button, not the panel behind it) gets increasingly darker until it reaches black.
If I hover over a (white) button in another part of the program first, then over any of these buttons the panels behind them become white instead of a darker version of the original color.
If I hover over any of these buttons, and then over another one of them afterwards, the second button seems to display the text of BOTH of the buttons.
Screenshots:
1: https://cdn.discordapp.com/attachments/871490774301294642/957684879712219168/unknown.png
2: https://cdn.discordapp.com/attachments/871490774301294642/957685306562338826/unknown.png
3: https://cdn.discordapp.com/attachments/871490774301294642/957685596900438086/unknown.png
Maybe I'm doing something blatantly wrong but I'm quite new to Swing so sorry if that is the case. Any help appreciated.
Related
I'm writing a program that trades out the main component of the GUI when a button is pressed. To do this, I have multiple classes extending a component (JScrollPane) that can then be placed into my main class, which extends JFrame.
JScrollPane menu;
public MenuSystem()
{
menu = new OpeningMenu(this);
setSize(500,500);
setLocationRelativeTo(null);
setTitle("Menu system");
setDefaultCloseOperation(EXIT_ON_CLOSE);
loadInfo();
pane = getContentPane();
pane.setLayout(null);
pane.add(menu);
setVisible(true);
}
public void changeMenuTo(JScrollPane x)
{
pane.remove(menu);
menu = x;
pane.add(menu);
pane.repaint();
}
These bits of code control which JScrollPane is displayed on the GUI. I face two problems that I believe are related.
When I start the program, some of the components in the initial JScrollPane do not appear. I have several buttons and a JLabel in this pane, but only the first button appears. The rest of the buttons will appear when my mouse passes over them, but until then, they are invisible. This seems strange, because it suggests that my constructor is somehow at fault. when bringing up the same pane with the changeMenuTo() method, it appears perfectly.
Whenever I manually resize the screen, all components in the current pane disappear. It happens almost exactly like when I first start the program, buttons are invisible until my mouse passes over them. In this case the first button is also invisible.
Changing the layout has fixed the issue. Thanks for the suggestions.
I'm working on a 2D game and am now stumped on a drawing issue. I'm repainting the JPanel with the background image and characters every frame, but the GUI is created in a setup function. I think that causes the JButton to appear behind the background image, and its worth mentioning this class extends JPanel. I'm using setBounds in order to arrange GUI elements a special way. What is a possible solution to this issue?
/** Draw game to the screen **/
private void gameDraw() {
Graphics g2 = this.getGraphics();
g2.drawImage(image, 0, 0 ,null);
g2.dispose();
}
public void SetupUI() {
uploadButton = new JButton("UPLOAD");
uploadButton.setBounds(WIDTH / 2, HEIGHT - 40, 50, 30);
uploadButton.setToolTipText("Press this button to upload your AI to the ship");
uploadButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//TO DO: Make upload button compile and run the users code
}
});
this.add(uploadButton);
this.setVisible(true);
}
I decided to redo the code for rendering the game component. The issue seems to have been the GUI button and the image sharing the same screen space, then the image redrawing over the button each frame. What I was trying to go for was the gui overlaid over the image, but I still do not know how to achieve that.
Instead I created two separate JPanels, one to hold the GUI elements in a 'ribbon' above the image, and one to hold the image where neither panels are overlapping then packed both of those into another panel which was then assigned to the JFrame (feel like this is a scene from the Emperors New Groove lol) . Each panel has a layout assigned. The image in its own panel can now be rendered as frequently as needed without interfering with the gui. Just remember to draw whatever images you want in order e.g. draw the background, then the player.
I couldn't solve the original problem, but this is a decent workaround.
So, I've been working on a program that lets you click/drag over a grid of JPanels, and changes the background colors of the JPanels that you have clicked on or dragged over (you can set the colors using JRadioButtons). I've gotten the point where if I click on a JPanel, it responds and changes colors. However, if I simply do:
public void mouseClicked(MouseEvent e){
((JPanel)e.getSource()).setBackground(color_chosen);
}
public void mouseDragged(MouseEvent e){
System.out.println("Calling mouseClicked"); // debugging
mouseClicked(e);
}
the program only responds to mouse clicks, and doesn't recolor the backgrounds of the JPanels affected by the mouse drag. In addition, its puzzling to me that "Calling mouseClicked" still prints out, but no background colors change.
I'd appreciate some help trying to figure out where I went wrong, so that any panel that I drag over changes its background color to a pre-specified chosen color.
Thanks.
In my app, I show a popup dialog to show a large list of cards. I display them as images in many JLabel components in a JPanel subclass. I then put that object in a JScrollPane to allow for horizontal scrolling through the cards.
I want the unused space to be transparent with a dark background to show that what's behind it is disabled. I used setBackground(new Color(50, 50, 50, 200)) to achieve the look I want, but the content behind it does not redraw, so I get artifacting.
Here's what it looks like:
How would I go about fixing this? How do I get the content behind it to redraw when I scroll?
Thanks in advance.
Taking the window out of the equation for the momement.
The JScrollPane contains a JViewport which then contains you content. So you need to set your content pane to transparent, the viewport to transparent and then the scroll pane to transparent.
You can achieve this by using setOpaque(false) on each of these containers.
This will ensure that the repaint manager will now paint through the background.
The next problem is, Swing doesn't actually support "semi-transparent" components (that is, either it's opaque or transparent).
You can implement this by overriding the paintComponent method of the main component (the one on the viewport is probably sufficient)
Try the following...might give you some relief during scrolling.
You likely also have a problem when the main frame is maximized
or restored. You will need a listener for those events and a
similar fix.
jScrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
#Override
public void adjustmentValueChanged(final AdjustmentEvent e) {
sevenWondersframe.repaint();
}
});
jScrollPane.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() {
#Override
public void adjustmentValueChanged(final AdjustmentEvent e) {
sevenWondersframe.repaint();
}
});
I'm trying to come up with an elegant recreation of the search bar component in Thunderbird. The clear button doesn't appear until there is text in the box, so that screen-shot is a bit inaccurate.
Should I use a layered pane and get some buttons to float above the box? (but then getting the text to not appear below the buttons would be hacky)
Maybe just put buttons at the ends of the search bar and have it somehow blend in?
Any ideas or maybe a style reconsideration is welcome, thank you.
What about a white panel with a border and a JTextField without borders inside. Two buttons (or more) in the west and east. Button will appear/hide depending on the text field content.
You might be able to use the Text Prompt for the "Search all text" display.
Check out JideSoft's Common Layer and the Overlayable class.
Demos
For building a very similar component I've used JXLayer (for drawing the buttons) in conjunction with IntelliHints from JIDE OSS project (for implementing a drop down list of values).
This code adds a label with given icon to the right of the JTextPane. One thing to work on: don't let the text go under the label. You can use setMargin(), but it shifts the label too.
JTextField searchField = new JTextField(30);
searchField.setLayout(new BorderLayout());
JLabel label = new JLabel(icon);
label.setCursor(Cursor.getDefaultCursor());
searchField.add(label, BorderLayout.LINE_END);
label.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
searchField.setText("");
}
});