I've looked around and viewed various threads on here. the one I found closest to what I'm attempting to do is this one:
Hovering over JButtons and displaying a message
Basically I'm trying to replace button.setToolTipText(""); with an ImageIcon. I'm using this as a preview of the next page you're about to visit inside the JFrame, to give to user an Idea or quick overview of the next page. (I have figured out the imaging, just not the ToolTip).
Here is what I tried using based on what I've seen in the various thread, but obviously it didn't work, hence I'm asking this question.
Code I used: Log.setToolTip(new ImageIcon(getIconLog));
You can use MouseListener and JLabel act as a tooltip. Like this...
public static void main(String[] args){
final JFrame f = new JFrame();
f.setSize(500, 400);
f.setVisible(true);
f.setLayout(null);
f.setDefaultCloseOperation(3);
final JButton b = new JButton("ToolTip");
b.setBounds(100, 100, 70, 70);
f.add(b);
final JLabel toolTip = new JLabel();
b.addMouseListener(new MouseListener() {
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
f.remove(toolTip);
f.repaint();
}
#Override
public void mouseEntered(MouseEvent e) {
try {
toolTip.setIcon(new ImageIcon(ImageIO.read(new File("your image"))));
} catch (IOException e1) {
e1.printStackTrace();
}
toolTip.setBounds(b.getLocation().x+b.getWidth(), b.getLocation().y-b.getHeight(), 100, 50);
f.add(toolTip);
f.repaint();
}
#Override
public void mouseClicked(MouseEvent e) {
}
});
}
Related
I am trying to remove from a specific frame panel#1 (which only contains a single JButton) and add to it panel#2, which contains some KeyEvents.
I was constantly getting a bug where the KeyEvents won't register, but while I was testing out some things, I found out that if I don't remove panel#1 and add panel#2 on top of the frame, the KeyListeners will register, only if the JButton on the panel#1 is not selected (only by pressing "TAB").
Can someone help me remove this bug?
This is panel#2:
public class paintTest extends JPanel implements KeyListener
{
public paintTest(){
addKeyListener(this);
setFocusable(true);
}
#Override
public void keyPressed(KeyEvent e) {}
#Override
public void keyReleased(KeyEvent e) {}
#Override
public void keyTyped(KeyEvent e) {}
}
And this is the Main class:
public static void main(String[] args)
{
JFrame mainMenu = new JFrame();
drawMainMenu(mainMenu);
mainMenu.setVisible(true);
mainMenu.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void drawMainMenu(JFrame frame)
{
frame.setBounds(0, 0, 360, 300);
frame.setLocationRelativeTo(null);
JPanel panel = new JPanel();
frame.add(panel);
JButton newGame = new JButton();
newGame.setBounds(130, 120, 100, 30);
newGame.setText("NEW GAME");
newGame.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent arg0)
{
paintTest gamePlay = new paintTest();
// frame.remove(panel); **HERE IS THE LINE OF CODE I WANT TO REMOVE**
frame.add(gamePlay);
frame.setBounds(0,0,512,512);
frame.setLocationRelativeTo(null);
}
});
panel.setLayout(null);
panel.add(newGame);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
I managed to fix it, thank you all:
One way to fix this is to make the JButton non-focusable by using:
.setfocusable(false);
This way the JButton will not be focused and marked, but still, when entering Panel#2 you will need to press "TAB" to focus again on the new Panel, and for that java.awt.Robot can be of use:
try {
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_TAB);
} catch (AWTException e) {
e.printStackTrace();
}
I have a JSplitPane with continuous layout turned on. How do I prevent other components from receiving mouse events while the divider is being dragged?
public class Test {
public static void main(String[] args) throws Exception {
JButton top = new JButton("top");
top.setRolloverEnabled(true);
top.setMinimumSize(new Dimension(100, 100));
top.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
top.setBackground(Color.green);
}
#Override
public void mouseExited(MouseEvent e) {
top.setBackground(null);
}
});
JButton bottom = new JButton("bottom");
bottom.setRolloverEnabled(true);
bottom.setMinimumSize(new Dimension(100, 100));
bottom.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
bottom.setBackground(Color.green);
}
#Override
public void mouseExited(MouseEvent e) {
bottom.setBackground(null);
}
});
JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
split.setResizeWeight(0.5);
split.setContinuousLayout(true);
split.setTopComponent(top);
split.setBottomComponent(bottom);
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(600, 400);
f.setLocationRelativeTo(null);
f.getContentPane().setLayout(new BorderLayout());
f.getContentPane().add(split, BorderLayout.CENTER);
f.setVisible(true);
}
}
How do I prevent other components from receiving mouse events while the divider is being dragged?
Don't know of a way to turn off all events.
But I'm guessing your real concern is that you don't want the background to change.
If so, then you can add exception logic to the MouseListener to ignore the mouseEntered event when the mouse button is pressed:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test {
public static void main(String[] args) throws Exception {
JButton top = new JButton("top");
top.setRolloverEnabled(true);
top.setMinimumSize(new Dimension(100, 100));
top.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) return;
top.setBackground(Color.green);
}
#Override
public void mouseExited(MouseEvent e) {
top.setBackground(null);
}
});
JButton bottom = new JButton("bottom");
bottom.setRolloverEnabled(true);
bottom.setMinimumSize(new Dimension(100, 100));
bottom.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) return;
bottom.setBackground(Color.green);
}
#Override
public void mouseExited(MouseEvent e) {
bottom.setBackground(null);
}
});
JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
split.setResizeWeight(0.5);
split.setContinuousLayout(true);
split.setTopComponent(top);
split.setBottomComponent(bottom);
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(600, 400);
f.setLocationRelativeTo(null);
f.getContentPane().setLayout(new BorderLayout());
f.getContentPane().add(split, BorderLayout.CENTER);
f.setVisible(true);
}
}
Edit:
Maybe you can use your own EventQueue. The EventQueue is responsible for dispatching events to the components. So maybe you can:
Add a MouseListener to the divider
on mousePressed you replace the default EventQueue with your custom EventQueue that will ignore MouseEvents for all components other than the divider.
on mouseRelease you restore the original EventQueue.
Check out Global Event Dispatching for a basic example to get you started.
the script works fine for dragging around one image but if I try to get two of them going at once it acts as if the class can only be called once? here is the code where i am adding two imageicons , but only one is showing:
import java.awt.*;
import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseAdapter;
public class TestMouseDrag {
public static void main(String[] args) {
new TestMouseDrag();
}
public TestMouseDrag() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new DragMyIcon("C:\\Users\\anon\\Desktop\\Hobbit.png")).setLocation(100, 100);
frame.add(new DragMyIcon("C:\\Users\\anon\\Desktop\\alien.png")).setLocation(100, 100)
frame.pack();
frame.setSize(700,700);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DragMyIcon extends JPanel {
public static final long serialVersionUID = 172L;
private JLabel label;
public DragMyIcon(String path) {
setLayout(null);
ImageIcon icon = null;
icon = new ImageIcon(path);
label = new JLabel(icon);
label.setBounds(0,0,100, 100);
label.setHorizontalAlignment(JLabel.CENTER);
label.setVerticalAlignment(JLabel.CENTER);
add(label);
MouseHandler handler = new MouseHandler();
label.addMouseListener(handler);
label.addMouseMotionListener(handler);
}
}
protected class MouseHandler extends MouseAdapter {
private boolean active = false;
private int xDisp;
private int yDisp;
#Override
public void mousePressed(MouseEvent e) {
active = true;
JLabel label = (JLabel) e.getComponent();
xDisp = e.getPoint().x - label.getLocation().x;
yDisp = e.getPoint().y - label.getLocation().y;
label.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
}
#Override
public void mouseReleased(MouseEvent e) {
active = false;
JLabel label = (JLabel) e.getComponent();
label.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
#Override
public void mouseDragged(MouseEvent e) {
if (active) {
JLabel label = (JLabel) e.getComponent();
Point point = e.getPoint();
label.setLocation(point.x - xDisp, point.y - yDisp);
label.invalidate();
label.repaint();
}
}
#Override
public void mouseMoved(MouseEvent e) {
}
}}
Your code does not respect the layout managers that it is using -- BorderLayout. When you add a component to a BorderLayout using container without specifying position, it is placed by default BorderLayout.CENTER and covers anything added previously.
Solution: read up on the layout managers including BorderLayout to see how to use them.
Also, you're probably better off not adding two DragMyIcon objects, but rather changing DragMyIcon so that it allows for multiple JLabels.
I am working on a project for class where a piece of code is displayed as an image and buttons are hidden where the errors are in the code. The idea being that the user can then click on the area of code where they think the error is and the button becomes visible- I have set it to be translucent red so the user can still the error underneath. What is happening in the code is the buttons are working, but when I hit another button the button takes on the view through the last button. For example the first button is over error 'j k' and when clicked it becomes red and can still see the error. However when hit the next button where the error is 'i+j' the first button then changes to display 'i+j' taking on the second buttons error. As the error is embedded in an image I am not quite sure how this is happening. Any help would be very welcome.
package gui;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Tutorial1Test extends JFrame {
private JPanel contentPane;
/**
*
*/
private static final long serialVersionUID = 1L;
JButton one = new JButton();
JButton two = new JButton();
JButton three = new JButton();
JButton four = new JButton();
JButton five = new JButton();
JButton six = new JButton();
JButton seven = new JButton();
JButton eight = new JButton();
JButton nine = new JButton();
int clickCount = 0;
/**
* Launch the application.
*
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Tutorial1Test frame = new Tutorial1Test();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Tutorial1Test() throws IOException {
//create, format and locate jframe
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//exit program when framed closed
setBounds(300, 75, 800, 600);
contentPane = new JPanel();
contentPane.setBackground(Color.WHITE);
setContentPane(contentPane);
contentPane.setLayout(null);
JLabel background = new JLabel(new ImageIcon("src/gui/Tutorial1TestImage.png"));
background.setBounds(0, 0, 800, 600);
contentPane.add(background);
JLabel count1 = new JLabel("count");
count1.setBounds(100,110,45,20);
//count1.setText(Integer.toString(clickCount));
contentPane.add(count1);
one = new JButton();
one.setBounds(100,110, 45, 20);
hideButton(one);
contentPane.add(one);
one.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
showButton(one);
} catch (Exception e) {
e.printStackTrace();
}
}
});
two = new JButton();
two.setBounds(100, 215, 45, 20);
hideButton(two);
contentPane.add(two);
two.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
showButton(two);
} catch (Exception e) {
e.printStackTrace();
}
}
});
three = new JButton();
three.setBounds(95, 240, 150, 20);
hideButton(three);
contentPane.add(three);
three.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
showButton(three);
} catch (Exception e) {
e.printStackTrace();
}
}
});
four = new JButton();
four.setBounds(275, 265, 45, 20);
hideButton(four);
contentPane.add(four);
four.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
showButton(four);
} catch (Exception e) {
e.printStackTrace();
}
}
});
five = new JButton();
five.setBounds(320, 365, 45, 20);
hideButton(five);
contentPane.add(five);
five.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
showButton(five);
} catch (Exception e) {
e.printStackTrace();
}
}
});
six = new JButton();
six.setBounds(35, 395, 45, 20);
hideButton(six);
contentPane.add(six);
six.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
showButton(six);
} catch (Exception e) {
e.printStackTrace();
}
}
});
seven = new JButton();
seven.setBounds(100, 440, 45, 20);
hideButton(seven);
contentPane.add(seven);
seven.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
showButton(seven);
} catch (Exception e) {
e.printStackTrace();
}
}
});
eight = new JButton("");
eight.setBounds(100, 520, 45, 20);
hideButton(eight);
contentPane.add(eight);
eight.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
showButton(eight);
} catch (Exception e) {
e.printStackTrace();
}
}
});
nine = new JButton("");
nine.setBounds(550, 545, 45, 20);
hideButton(nine);
contentPane.add(nine);
nine.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
showButton(nine);
} catch (Exception e) {
e.printStackTrace();
}
}
});
//after you create your panel
contentPane.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent evt) {
if (evt.getClickCount() >=12) {
//close window
}
else {
//display number of clicks
clickCount = evt.getClickCount();
}
}
});
}
public static void hideButton(JButton button){
//change button settings so not visible on opening
button.setFocusPainted(false);
button.setContentAreaFilled(false);
button.setBorderPainted(false);
button.setOpaque(false);
}
public static void showButton(JButton button){
//change button back to visible but transparent with colour to highlight error
button.setOpaque(true);
button.setContentAreaFilled(true);
button.setBackground(new Color(255,0,0,25));
}
}
I would do things differently:
I would give my program an array of Rectangles or ArrayList<Rectangle> and fill the collection with a list of the "active" rectangles on the image.
I would give my program a Rectangle variable, say called pressedRect that is initially set to null.
I would have my gui class extend JPanel and give it a MouseListener.
In this listener's mousePressed(...) method, I would iterate through the Rectangles in the array or collection to see if any of them have been pressed.
If pressed, I would set the pressedRect variable to the Rectangle identified in the Mouselistener.
I would draw the image in the paintComponent(...) method of a JPanel.
In the same paintComponent(...) method, I'd check if pressedRect is null and if not, I'd fill it in using Graphics2D#fill(...) method. You could use a translucent color for this such as new Color(0, 80, 0, 80).
Does somebody know how to remove white rectangle border on JButton ? This issue is there only for windows look & feel when the button is a little bit rounded.
Please find attached the example on the image.
Setting the border to empty or null doesn't help. The same for margin.
The white margin/border dissapear only when I set the opacity of the button to false, but unfortunately in this case also the whole button is opaque on some versions of windows.
When I set opacity to false, it looks like:
Code example:
public class TestFrame extends javax.swing.JFrame {
/**
* Auto-generated main method to display this JFrame
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
TestFrame inst = new TestFrame();
inst.setLocationRelativeTo(null);
inst.setVisible(true);
}
});
}
public TestFrame() {
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
this.setLayout(null);
this.getContentPane().setBackground(Color.BLACK);
JButton button = new JButton();
button.setBounds(10, 10, 100, 50);
button.setBorder(BorderFactory.createEmptyBorder()); // not working
button.setBorder(null); // not working
button.setMargin(new Insets(0,0,0,0)); // not working
add(button);
pack();
setSize(400, 300);
}
}
Thanks,
Lubos
Seems like a painting problem. You can use:
button.setBackground( Color.BLACK );
EDIT: See comments below. This sample still shows the effect, even using a proper layout. Setting the background color seems to show the unwanted border. This effect doesn't show with Metal. It seems as if Windows L&F shows a rounded edge, but the button is still rectangular. The space between is only noticable if the BG color of the container is changed to something obvious, like black.
import java.awt.*;
import javax.swing.*;
public class TestFrame extends JFrame
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception e)
{
e.printStackTrace();
}
TestFrame inst = new TestFrame();
inst.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
inst.setLocationRelativeTo(null);
inst.setVisible(true);
}
});
}
public TestFrame()
{
JButton button = new JButton("One");
JButton button2 = new JButton("Two");
JPanel p = new JPanel();
p.setBackground(Color.BLACK);
p.setLayout(new FlowLayout());
p.add(button);
p.add(button2);
add(p);
setSize(400, 300);
}
}