Why isn't mouselistener working? - java

Here's the code. It prints out the mouse location when it's in the panel but not the JTextArea. I added the mouse listener to the text area as well? The problem is that the coordinates are not consistent throughout the JFrame. Is there a way to just have one mouselistener that covers the entire jframe?
Is there a way to disable the mouse listener in the textarea?
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class test extends JFrame {
public test(){
setPreferredSize(new Dimension(600,400));
JPanel p = new JPanel();
p.setBackground(Color.blue);
p.setPreferredSize(new Dimension(600,200));
JTextArea t = new JTextArea();
t.setPreferredSize(new Dimension(600,200));
add(p,BorderLayout.NORTH);
add(t,BorderLayout.SOUTH);
pack();
MouseInput m = new MouseInput();
addMouseMotionListener(m);
t.addMouseMotionListener(m);
setVisible(true);
}
public static void main(String[] args){
new test();
}
public class MouseInput implements MouseMotionListener{
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
int mx = e.getX();
int my = e.getY();
System.out.println(mx + "," + my);
}
}
}

Think of your mouse events like rain. They fall from the top of your component hierarchy down until something stops them.
Once stopped, they will no long notify other listeners lower in the hierarchy.
In you program you have and JPanel and JTextField sitting on top of another component (the content pane) sitting on a JLayeredPane sitting on top of the frame. Any one of these may be consuming the mouse event.
Try adding the MouseInput to your JPanel, p instead
Updated
This is an example of a global mouse listener (as suggested by #Hovercraft Full Of Eels, it WILL get hammered, as every mouse event will pass through it.
It also demonstrates how to translate a mouse point from it's local context to another context.
import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class GloablMouseListener {
public static void main(String[] args) {
new GloablMouseListener();
}
public GloablMouseListener() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
JPanel panel = new JPanel();
panel.setBackground(Color.BLUE);
JTextArea ta = new JTextArea(10, 20);
add(panel, BorderLayout.NORTH);
add(new JScrollPane(ta), BorderLayout.SOUTH);
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
#Override
public void eventDispatched(AWTEvent event) {
if (event instanceof MouseEvent) {
MouseEvent e = (MouseEvent) event;
System.out.println("Local point = " + e.getPoint());
Point p = e.getPoint();
Window window = SwingUtilities.getWindowAncestor(e.getComponent());
if (window != e.getSource() && window != null) {
p = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), window);
}
System.out.println("Global point = " + p);
}
}
}, AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}

The JTextArea has its own MouseListener/MouseMotionListener that grabs the mouse information before any underlying class with a MouseListener or motion listener can.
This may be fixable by using an AWTEventListener, but I have not tried this myself yet.
Edit
OK, I have tried this as a for instance:
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class Test2 extends JPanel {
JTextArea textarea = new JTextArea(15, 60);
public Test2() {
JPanel topPanel = new JPanel();
topPanel.setBackground(Color.blue);
setLayout(new GridLayout(0, 1));
add(topPanel);
add(new JScrollPane(textarea));
addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
int x = e.getX();
int y = e.getY();
System.out.printf("%20s [%03d, %03d]%n", "From MouseAdapter:", x, y);
}
});
long eventMask = AWTEvent.MOUSE_MOTION_EVENT_MASK;
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
#Override
public void eventDispatched(AWTEvent awtEvent) {
MouseEvent mouseEvent = (MouseEvent) awtEvent;
Component component = (Component) awtEvent.getSource();
Point location = component.getLocationOnScreen();
Point test2Location = Test2.this.getLocationOnScreen();
// Normalized to find the mouse location relative to the main JPanel,
// the Test2 "this" JPanel.
int x = mouseEvent.getX() + location.x - test2Location.x;
int y = mouseEvent.getY() + location.y - test2Location.y;
System.out.printf("%20s [%03d, %03d]%n", "From AWTEvent:", x, y);
}
}, eventMask );
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Test2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Test2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Try adding a MouseListener to your application's GlassPane.
See these following link. It includes a Java Web Start demo of something similar to what you want to do.
How to Use Root Panes

Related

jSplitPane Showing and Hiding Left Pane when Mouse over

I'm working on an application that allows me to show and hide split planes.
I've read some articles on how to get this but its not what I'm looking for.
here's the code Ive written:
Im currently using netbeans.
private void jSplitPane1MouseEntered(java.awt.event.MouseEvent evt) {
if(MouseInfo.getPointerInfo().getLocation() == jSplitPane1.getLeftComponent().getLocation()){
jSplitPane1.setDividerLocation(100);
System.out.println("Mouse Entered");
}else{
jSplitPane1.setDividerLocation(20);
System.out.println("Mouse Exited");
}
}
I have referred to these posts:
How to make JSplitPane auto expand on mouse hover?
Get Mouse Position
What I want to happen is when I mouse over the left side of the jSplitPane, I would get the divider to extend to 100 as per my first if statement, and when it exists the left side, it contracts back to divider location 20.
This is really, really tricky.
You could use a MouseListener on the "left" component and monitor the mouseEntered and mouseExited events, but these will also get triggered when when you move into and out of a child component which has a MouseListener of it's own (like a JButton).
Okay, you could use a MouseMotionListener on the JSplitPane and monitor for the mouseMoved event and check where the mouse cursor is, but this goes to hell the moment the components (left/right) get their own MouseListener, as the MouseEvents are no longer delivered to the JSplitPane
So, one of the last options you have is to attach a global AWTListener to the event queue and monitor for events which occur on the JSplitPane itself, for example...
import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
JSplitPane pane = new JSplitPane();
pane.setLeftComponent(makePane(Color.RED));
pane.setRightComponent(makePane(Color.BLUE));
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
#Override
public void eventDispatched(AWTEvent event) {
if (event instanceof MouseEvent) {
MouseEvent me = (MouseEvent) event;
if (pane.getBounds().contains(me.getPoint())) {
System.out.println("Global Motion in the pane...");
me = SwingUtilities.convertMouseEvent(me.getComponent(), me, pane);
Component left = pane.getLeftComponent();
if (left.getBounds().contains(me.getPoint())) {
pane.setDividerLocation(100);
} else {
pane.setDividerLocation(20);
}
}
}
}
}, MouseEvent.MOUSE_MOTION_EVENT_MASK);
// You don't need this, this is to demonstrate
// that mouse events aren't hitting your component
// via the listener
pane.addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
System.out.println("Motion in the pane...");
Component left = pane.getLeftComponent();
if (left.getBounds().contains(e.getPoint())) {
pane.setDividerLocation(100);
} else {
pane.setDividerLocation(20);
}
}
});
pane.setDividerLocation(20);
add(pane);
}
protected JPanel makePane(Color background) {
JPanel pane = new JPanel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 100);
}
};
pane.setLayout(new GridBagLayout());
pane.add(new JButton("..."));
pane.setBackground(background);
pane.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("...");
}
});
return pane;
}
}
}

JPanel created on click not appearing

The below code is not my actual code but a concise, runnable remake of what I am trying to achieve. I want the JPanel CP, an instance of clickPanel, to appear when the user clicks on the image in JPanel hasAnImage. I can see in the Netbeans console that the is executing because of the Sys.out.print, but nothing appears on the screen. I have tried setting visible to false then true again and revalidate() in the mousePressed event; the image moves to the left, but nothing appears on the screen. The goal is for CP to appear. What am I missing? Hope my question is clear.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Testo extends JFrame{
public Testo(){
BufferedImage image = null;
try {
image = ImageIO.read(new File("C:\\Users\\someimage.jpg"));
} catch (IOException ex) {
ex.printStackTrace();
}
;
final JLabel label = new JLabel(new ImageIcon(image));
JPanel hasAnImage = new JPanel();
hasAnImage.addMouseListener(new MouseAdapter(){
#Override //I override only one method for presentation
public void mousePressed(MouseEvent e) {
clickPanel CP = new clickPanel();
hasAnImage.add(CP);
revalidate();
//setVisible(false);
//setVisible(true);
}
});
hasAnImage.add(label);
add(hasAnImage);
setVisible(true);
}
public static void main(String[] args) {
Testo frame = new Testo();
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.getContentPane().setBackground(Color.WHITE);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public class clickPanel extends JPanel{
public clickPanel() {
setPreferredSize(new Dimension(100,60));
setMaximumSize(new Dimension(100,60));
setBackground(new Color(1.0f,1.0f,1.0f,0.1f));
setBorder(BorderFactory.createMatteBorder(2,2,2,2,Color.GREEN));
System.out.println("This is being executed...");
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setFont(new Font("Arial", Font.PLAIN, 12));
g.setColor(Color.GREEN);
g.drawString("CLICK", 2, 2);
}
}
}
Beyond revalidate();ing the pane, you also need to repaint(); it. Thus your mousePressed method should become:
public void mousePressed(MouseEvent e) {
clickPanel CP = new clickPanel();
hasAnImage.add(CP);
revalidate();
repaint();
}
For further reading: http://docs.oracle.com/javase/7/docs/api/java/awt/Component.html#repaint()

How do I make my JWindow window always stay focused

I am making a java application that includes a JWindow. I want to be able to track the mouse without the user having to click the window after going to another window.
Your question is little vague on why you want to continue processing the mouse once it's left the JWindow...but
You have two (basic) choices when it comes to mointoring the mouse outside of your application, you can use a JNI/JNA solution or you can poll MouseInfo.
The following demonstrates the latter, using MouseInfo and a javax.swing.Timer to update a label...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.MouseInfo;
import java.awt.PointerInfo;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MouseWindow {
public static void main(String[] args) {
new MouseWindow();
}
public MouseWindow() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel label;
public TestPane() {
setLayout(new BorderLayout());
label = new JLabel();
label.setFont(label.getFont().deriveFont(48f));
label.setHorizontalAlignment(JLabel.CENTER);
label.setVerticalAlignment(JLabel.CENTER);
add(label);
updateMouseInfo();
Timer timer = new Timer(250, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
updateMouseInfo();
}
});
timer.start();
}
protected void updateMouseInfo() {
PointerInfo pi = MouseInfo.getPointerInfo();
label.setText(pi.getLocation().x + "x" + pi.getLocation().y);
}
}
}
Updated
You may also find Window#setAlwaysOnTop of help to keep the window ontop of the others, if support for the platform

Drawing on JPanel behind GlassPane when clicking on GlassPane

Okay So I looked through multiple forums and Google and couldn't find an answer to my specific problem. So I have two panels stacked on top of each other and the one on top is a glassPane. When you drag your mouse around the glassPane it draws a vertical red line at the cursor,which works, but when I click on the glassPane I want it it draw a black line at the cursor position on the panel below the glassPane. I can get it to redirect the mouseClick to the bottom panel but it wont draw the line. It just makes the redline disappear until you move the mouse again. Also If I set the glassPane invisible and click on the bottom panel the line is drawn so the drawing code works just fine. Thanks in advance.
Main Class
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Robot;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
public class LiveField extends JPanel {
/**
* Create the panel.
*/
static JFrame frame;
static JPanel ContentPane;
private JPanel panel;
private MyGlassPane glassPane;
public static void main(String[] args) throws AWTException
{
LiveField live = new LiveField();
frame.setVisible(true);
}
public LiveField() throws AWTException {
frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1000, 433);
setLayout(new BorderLayout(0, 0));
ContentPane = new JPanel();
frame.setContentPane(ContentPane);
ContentPane.setLayout(new BorderLayout(0, 0));
panel = new JPanel()
{
public void paintComponent(Graphics g) {
super.paintComponent(g);
panel.setBackground(new Color(50,160,55));
}
};
glassPane = new MyGlassPane(panel);
frame.setGlassPane(glassPane);
glassPane.setVisible(true);
panel.addMouseListener(new MouseAdapter() {
int[] pos = new int[2];
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("Handles click event");
Graphics g = panel.getGraphics();
g.setColor(new Color(50,165,55));
g.drawLine(pos[0], pos[1], 0+pos[0], 0);//to top
g.drawLine(pos[0], pos[1], 0+pos[0], panel.getHeight());//to bottom
int y = e.getYOnScreen();
int x = e.getXOnScreen();
pos[0]= x;
pos[1] = y;
g.setColor(new Color(0,0,0));
g.drawLine(x, y, 0+x, 0);//to top
g.drawLine(x, y, 0+x, panel.getHeight());//to bottom
g.dispose();
}
});
ContentPane.add(panel, BorderLayout.CENTER);
}
GlassPane Class
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import javax.swing.JComponent;
class MyGlassPane extends JComponent implements ItemListener {
Point point;
protected void paintComponent(Graphics g) {
}
public void setPoint(Point p) {
point = p;
}
public MyGlassPane(final Container contentPane) throws AWTException {
final Component glass = this;
addMouseMotionListener(new MouseMotionListener()
{
ArrayList<Integer> line = new ArrayList<Integer>();
Robot rb = new java.awt.Robot();
#Override
public void mouseMoved(MouseEvent e) {
//System.out.println("Moving");
Graphics g = glass.getGraphics();
if(!line.isEmpty())
{
//System.out.println("line is not empty");
g.setColor(new Color(50,160,55));
g.drawLine(line.get(0), line.get(1), 0+line.get(0), 0);//to top
g.drawLine(line.get(0), line.get(1), 0+line.get(0), contentPane.getHeight());//to bottom
}
//System.out.println("draw line");
int x = e.getXOnScreen();
int y = e.getYOnScreen();
Color col = rb.getPixelColor(x, y);
//System.out.println(col.toString() + " : " + Color.white.toString());
//System.out.println(col.equals(new Color(255,255,255)));
if(!col.equals(new Color(255,255,255)) && !inEndZone(x))
{
g.setColor(new Color(255,0,0));
line = new ArrayList<Integer>();
line.add(x);line.add(y);
g.drawLine(x, y, 0+line.get(0), 0);//to top
g.drawLine(x, y, 0+line.get(0), contentPane.getHeight());//to bottom
}
g.dispose();
}
private boolean inEndZone(int x) {
int ends = contentPane.getWidth()/10;
//System.out.println(x + " : " + ends);
if(x<ends)
{
//System.out.println("In endzone");
return true;
}
else if(x>contentPane.getWidth()-ends)
{
return true;
}
else
{
return false;
}
}
#Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
}
});
addMouseListener(new CBListener(this,contentPane));
}
#Override
public void itemStateChanged(ItemEvent e) {
// TODO Auto-generated method stub
setVisible(e.getStateChange() == ItemEvent.SELECTED);
}
}
Listener Class ( for dispatching the mouse click)
import java.awt.Component;
import java.awt.Container;
import java.awt.Point;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import javax.swing.SwingUtilities;
import javax.swing.event.MouseInputAdapter;
class CBListener extends MouseInputAdapter {
Toolkit toolkit;
Robot rb;
MyGlassPane glassPane;
Container contentPane;
public CBListener(MyGlassPane glassPane, Container contentPane) {
toolkit = Toolkit.getDefaultToolkit();
this.glassPane = glassPane;
this.contentPane = contentPane;
}
#Override
public void mouseClicked(MouseEvent e) {
redispatchMouseEvent(e, false);
}
// A basic implementation of redispatching events.
private void redispatchMouseEvent(MouseEvent e, boolean repaint) {
Point glassPanePoint = e.getPoint();
Container container = contentPane;
Point containerPoint = SwingUtilities.convertPoint(glassPane,
glassPanePoint, contentPane);
if (containerPoint.y < 0) { // we're not in the content pane
} else {
// The mouse event is probably over the content pane.
// Find out exactly which component it's over.
Component component = SwingUtilities.getDeepestComponentAt(
container, containerPoint.x, containerPoint.y);
if ((component != null) && (component.equals(contentPane))) {
System.out.println("contentPane");
// Forward events over the check box.
Point componentPoint = SwingUtilities.convertPoint(glassPane,
glassPanePoint, component);
component.dispatchEvent(new MouseEvent(component, e.getID(), e
.getWhen(), e.getModifiers(), componentPoint.x,
componentPoint.y, e.getClickCount(), e
.isPopupTrigger()));
}
}
// Update the glass pane if requested.
if (repaint) {
glassPane.setPoint(glassPanePoint);
glassPane.repaint();
}
}
}
I can get it to redirect the mouseClick to the bottom panel but it
wont draw the line. It just makes the redline disappear until you move
the mouse again
No, It is drawing black line indeed. But the line is drawn above the red line that makes the red line to vanish till the mouse is moved again . I Guess you are looking for something like this:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class DoublePanel extends JFrame
{
JPanel mainPanel;
int x1;
public void prepareAndShowGUI()
{
setTitle("DoublePanel");
mainPanel = new JPanel()
{
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.BLACK);
g.drawLine(x1,0,x1,this.getHeight());
}
};
mainPanel.setBackground(new Color(50,160,55));
mainPanel.setLayout(new BorderLayout());
mainPanel.add(new upperPanel(this));
setContentPane(mainPanel);
setSize(500,600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setVisible(true);
}
public void setXValue(int x)
{
this.x1 = x;
mainPanel.repaint();
}
class upperPanel extends JPanel
{
int x; int y;
DoublePanel dp;
upperPanel(DoublePanel d)
{
this.dp = d;
setOpaque(false);
addMouseMotionListener(new MouseAdapter()
{
#Override
public void mouseMoved(MouseEvent evt)
{
x = evt.getX();
y = evt.getY();
repaint();
}
});
addMouseListener(new MouseAdapter()
{
#Override
public void mouseClicked(MouseEvent evt)
{
dp.setXValue(evt.getX());
}
});
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.RED);
g.drawLine(x,0,x,this.getHeight());
}
}
public static void main(String st[])
{
SwingUtilities.invokeLater( new Runnable()
{
public void run()
{
DoublePanel dp = new DoublePanel();
dp.prepareAndShowGUI();
}
});
}
}
You need to call the bottom panel's repaint().

Java tabbed panes within internal frame

I am trying to get an internal frame to contain tabbed panes. However, my code does not seem to be loading the panes into the internal frame. I have my code in the java files, called InternalFrame.java and TabbedPaneSample.java. The code for both files is included below. Can anyone show me how to fix the code below so that it loads the tabbed panes when I run InternalFrame.java?
Here is my code:
The code for InternalFrame.java is:
package test;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLayeredPane;
public class InternalFrame extends JFrame {
JButton openButton;
JLayeredPane desktop;
JInternalFrame internalFrame;
TabbedPaneSample myTabbedPaneSample = new TabbedPaneSample();
public InternalFrame() {
super("Click button to open internal frame with two panels.");
setSize(500, 400);
openButton = new JButton("Open");
Panel p = new Panel();
p.add(openButton);
add(p, BorderLayout.SOUTH);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
openButton.addActionListener(new OpenListener());
desktop = new JDesktopPane();
desktop.setOpaque(true);
add(desktop, BorderLayout.CENTER);
}
class OpenListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if ((internalFrame == null) || (internalFrame.isClosed())) {
internalFrame = new JInternalFrame("Internal Frame", true, true, true, true);
internalFrame.setBounds(50, 50, 200, 100);
internalFrame.add(myTabbedPaneSample, BorderLayout.CENTER);
internalFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
internalFrame.pack();
internalFrame.setMinimumSize(new Dimension(300, 300));
desktop.add(internalFrame, new Integer(1));
internalFrame.setVisible(true);
}
}
}
public static void main(String args[]) {
InternalFrame myInternalFrame = new InternalFrame();
myInternalFrame.setVisible(true);
}
}
And the code for TabbedPaneSample.java is:
package test;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
public class TabbedPaneSample extends JTabbedPane {
private JTabbedPane tabbedPane = new JTabbedPane();
private ImageIcon closeImage = new ImageIcon("C:/test/shipIcon.gif");
private Dimension closeButtonSize;
private int tabCounter = 0;
public TabbedPaneSample() {
closeButtonSize = new Dimension(closeImage.getIconWidth() + 2, closeImage.getIconHeight() + 2);
}
public void add() {
final JPanel content = new JPanel();
JPanel tab = new JPanel();
tab.setOpaque(false);
JLabel tabLabel = new JLabel("Tab " + (++tabCounter));
JButton tabCloseButton = new JButton(closeImage);
tabCloseButton.setPreferredSize(closeButtonSize);
tabCloseButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int closeTabNumber = tabbedPane.indexOfComponent(content);
tabbedPane.removeTabAt(closeTabNumber);
}
});
tab.add(tabLabel, BorderLayout.WEST);
tab.add(tabCloseButton, BorderLayout.EAST);
this.addTab(null, content);
this.setTabComponentAt(this.getTabCount() - 1, tab);
}
public static void main(String[] args) {
TabbedPaneSample main = new TabbedPaneSample();
main.add();
main.add();
}
}
Here's one approach, shown below. A more flexible approach using Action is referenced here.
Addendum: Reviewing your code, you should let the various layout managers and component preferred sizes do more of the work, as shown. In particular, this.setPreferredSize() is done for demonstration purposes. In a real application, you would restore user size and location preferences.
package overflow;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
/** #see https://stackoverflow.com/posts/6514889 */
public class InternalFrame extends JFrame {
JButton openButton;
JLayeredPane desktop;
JInternalFrame internalFrame;
public InternalFrame() {
super("Click button to open internal frame with two tabs.");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setPreferredSize(new Dimension(400, 400));
openButton = new JButton("Open");
JPanel p = new JPanel();
p.add(openButton);
this.add(p, BorderLayout.SOUTH);
openButton.addActionListener(new OpenListener());
desktop = new JDesktopPane();
this.add(desktop, BorderLayout.CENTER);
this.pack();
this.setLocationRelativeTo(null);
}
class OpenListener implements ActionListener {
private static final int DELTA = 40;
private int offset = DELTA;
public void actionPerformed(ActionEvent e) {
internalFrame = new JInternalFrame(
"Internal Frame", true, true, true, true);
internalFrame.setLocation(offset, offset);
offset += DELTA;
internalFrame.add(createTabbedPane());
desktop.add(internalFrame);
internalFrame.pack();
internalFrame.setVisible(true);
}
}
private JTabbedPane createTabbedPane() {
JTabbedPane jtp = new JTabbedPane();
createTab(jtp, "One");
createTab(jtp, "Two");
return jtp;
}
private void createTab(JTabbedPane jtp, String s) {
jtp.add(s, new JLabel("TabbedPane " + s, JLabel.CENTER));
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
InternalFrame myInternalFrame = new InternalFrame();
myInternalFrame.setVisible(true);
}
});
}
}
First of all, I think Finally, I think you shouldn't use desktop.add(internalFrame, new Integer(1)) but rather desktop.add(internalFrame) instead, the reason is that JDesktopPane uses its layers (it is a JLayeredPane subclass) internally, and I don't think you should play with layers yourself.
Then, following this problem I had once with JInternalFrame, I would advise you call pack() after adding the internal frame to the desktop pane.
Hence, you should try with your OpenListener class looking like this:
class OpenListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if ((internalFrame == null) || (internalFrame.isClosed())) {
internalFrame = new JInternalFrame("Internal Frame", true, true, true, true);
internalFrame.setBounds(50, 50, 200, 100);
internalFrame.add(myTabbedPaneSample, BorderLayout.CENTER);
internalFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// internalFrame.pack();
internalFrame.setMinimumSize(new Dimension(300, 300));
// desktop.add(internalFrame, new Integer(1));
desktop.add(internalFrame);
internalFrame.pack();
internalFrame.setVisible(true);
}
}
}
Besides, I also agree with trashgod comments on Action of course and the simplifying rework he has done on your snippet.
I preferred to create in my Main Frame class (which extends JFrame) the following function:
private void showIntFrame(Class intFrameClass) {
JInternalFrame targetFrame = null;
int xoff = 0, yoff = 0;
for(JInternalFrame jif : jdp.getAllFrames()) {
if(jif.getClass().equals(intFrameClass))
targetFrame = jif;
if(jif.getLocation().x > xoff)
xoff = jif.getLocation().x;
if(jif.getLocation().y > yoff)
yoff = jif.getLocation().y;
}
if(targetFrame == null) {
try {
Constructor<JInternalFrame> c = intFrameClass.getConstructor(MainFrame.class);
targetFrame = c.newInstance(MainFrame.this);
} catch (Exception ex) {
System.err.println("Exception in MainFrame.showIntFrame() while creating new JInternalFrame instance. " + ex.getLocalizedMessage());
ex.printStackTrace();
return;
}
jdp.add(targetFrame);
targetFrame.setLocation(xoff + 30, yoff + 30);
}
targetFrame.setVisible(true);
try {
targetFrame.setSelected(true);
} catch (PropertyVetoException ex) {
System.err.println("PropertyVetoException in MainFrame.showIntFrame() while activating JInternalFrame instance. " + ex.getLocalizedMessage());
}
}
Here jdp is instance of JDesktopPane, which previously was set as ContentPane of my main JFrame.
Because my programs often contain numbers of different classes, inherited from JInternalFrame, it is easier to call this function from event handlers to show new subclass of JInternalFrame.
Every subclass of JInternalFrame in my programs have one constructor with one parameter - MainFrame (main JFrame).

Categories

Resources