When the addComponents() method is run once, I get the desired layout of my JPanel. However, when the code in addComponents() is executed more than once, the layout of the JPanel is completely wrong. Is there anything that I seem to be doing wrong?
public class DeleteStudent extends JPanel {
public SearchPanel search = new SearchPanel();
private final JButton deleteButton = new JButton("Delete from database");
private GridBagConstraints cons = new GridBagConstraints();
private final GridBagLayout gridBag = new GridBagLayout();
public DeleteStudent() {
super();
setLayout(gridBag);
setPreferredSize(new Dimension(400, 300));
addComponents();
addComponents(); //Method fails when run more than once!
}
public void addComponents() {
cons.gridy = 1;
cons.insets = new Insets(50, 0, 0, 0);
gridBag.setConstraints(deleteButton, cons);
removeAll();
add(search);
add(deleteButton);
update();
}
private void update() {
revalidate();
repaint();
}
Screenshots:
JPanel after 1 method call: http://img402.imageshack.us/img402/6409/oncer.png
JPanel after 2 method calls: http://imageshack.us/scaled/landing/254/twiced.png
Adding to my comment:
Seems problem is you set the JPanels GridBagLayout constraints before calling removeAll() it should be done after calling removeAll(); so that when we add the new components the LayoutManager is still in effect and hasnt been reset to its defaults values.
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public Test() {
createAndShowGui();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Test();
}
});
}
private void createAndShowGui() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DeleteStudent());
frame.pack();
frame.setVisible(true);
}
}
class DeleteStudent extends JPanel {
public JPanel search = new JPanel() {//for testing
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
};
private final JButton deleteButton = new JButton("Delete from database");
private GridBagConstraints cons = new GridBagConstraints();
private final GridBagLayout gridBag = new GridBagLayout();
public DeleteStudent() {
super();
setLayout(gridBag);
addComponents();
addComponents(); //Method fails when run more than once!
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
public void addComponents() {
removeAll();//must call this before resetting Layout and adding new components
cons.gridy = 1;
cons.insets = new Insets(50, 0, 0, 0);
gridBag.setConstraints(deleteButton, cons);
add(search);
add(deleteButton);
update();
}
private void update() {
revalidate();
repaint();
}
}
Related
I have 3 frames, Main (as the parent) and 2 JInternalFrames (F1 and F2 as children). When a button (inside parent) is pressed, I make an instance of F1 and send it as a parameter to ShowIntrlFrame() so F1 can be displayed inside frmContainter. My question here is, how can I open F2 from F1 and display it on frmContrainer (which is in the Main frame)?
public class Main extends javax.swing.JFrame{
public Main(){
}
private void btnOpenFrmActionPerformed(java.awt.event.ActionEvent evt) {
F1 f1 = new F1();
frmContainer(f1);
}
}
public void ShowIntrlFrame(JInternalFrame f){
f.setSize(1100, 620);
f.setLocation(0, 0);
f.setVisible(true);
frmContainer.removeAll();
frmContainer.add(f, BorderLayout.CENTER);
frmContainer.revalidate();
frmContainer.repaint();
}
What I would do is follow a delegation pattern via dependency injection.
This is, I would "delegate" the functionality need to generate and show the window to some other class and then "inject" that into the workflow as required
I'd start with a concept of a "window manager"...
public interface WindowManager {
enum Window {
FIRST, SECOND;
}
public void openWindow(Window window);
}
At the moment, this is pretty basic and just opens a specified window. The nice thing about this, is we don't care if it's a JInternalFrame or JFrame which gets generated, that's not the callers responsibility.
Next, we make a implementation which supports JDesktopPane
public class DesktopWindowManage implements WindowManager {
private JDesktopPane desktopPane;
private int initialX = 0;
private int initialY = 0;
public DesktopWindowManage(JDesktopPane desktopPane) {
this.desktopPane = desktopPane;
}
public JDesktopPane getDesktopPane() {
return desktopPane;
}
#Override
public void openWindow(Window window) {
JInternalFrame frame = new JInternalFrame(window.name(), true, true, true, true);
frame.setContentPane(makeContentFor(window));
frame.pack();
frame.setLocation(initialX, initialY);
frame.setVisible(true);
try {
frame.setSelected(true);
} catch (PropertyVetoException ex) {
}
desktopPane.add(frame);
frame.toFront();
initialX += 20;
initialY += 20;
}
protected JPanel makeContentFor(Window window) {
switch (window) {
case FIRST: return new FirstPane(this);
case SECOND: return new SecondPane();
}
return null;
}
}
Now, important to note, this class is acting as kind of factory, in that it's generating the content view and JInternalFrame. I'd probably consider making a "content factory" which could be injected into this which would then create the content based on the desired destination, but that's probably getting a little more complicated then is required right now.
Now, before you ask, the actual content is based on JPanel, for example...
public class FirstPane extends JPanel {
public FirstPane(WindowManager windowManager) {
setBorder(new EmptyBorder(32, 32, 32, 32));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = gbc.REMAINDER;
add(new JLabel("I am first"), gbc);
JButton showSecond = new JButton("Show second");
showSecond.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
windowManager.openWindow(WindowManager.Window.SECOND);
}
});
add(showSecond, gbc);
}
}
public class SecondPane extends JPanel {
public SecondPane() {
setBorder(new EmptyBorder(32, 32, 32, 32));
setLayout(new GridBagLayout());
add(new JLabel("I am second"));
}
}
Why? Because it's a JPanel can be added to any container and, generally, we don't care if it's a JInternalFrame or JFrame.
And finally, some kind of "starting point"....
public class MainPane extends JPanel {
private WindowManager windowManager;
private JDesktopPane desktopPane;
public MainPane() {
setLayout(new BorderLayout());
JButton open = new JButton("Open");
desktopPane = new JDesktopPane() {
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
};
windowManager = new DesktopWindowManage(desktopPane);
add(open, BorderLayout.NORTH);
add(desktopPane);
open.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
windowManager.openWindow(WindowManager.Window.FIRST);
}
});
}
}
Runnable example...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyVetoException;
import javax.swing.JButton;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new MainPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface WindowManager {
enum Window {
FIRST, SECOND;
}
public void openWindow(Window window);
}
public class DesktopWindowManage implements WindowManager {
private JDesktopPane desktopPane;
private int initialX = 0;
private int initialY = 0;
public DesktopWindowManage(JDesktopPane desktopPane) {
this.desktopPane = desktopPane;
}
public JDesktopPane getDesktopPane() {
return desktopPane;
}
#Override
public void openWindow(Window window) {
JInternalFrame frame = new JInternalFrame(window.name(), true, true, true, true);
frame.setContentPane(makeContentFor(window));
frame.pack();
frame.setLocation(initialX, initialY);
frame.setVisible(true);
try {
frame.setSelected(true);
} catch (PropertyVetoException ex) {
}
desktopPane.add(frame);
frame.toFront();
initialX += 20;
initialY += 20;
}
protected JPanel makeContentFor(Window window) {
switch (window) {
case FIRST: return new FirstPane(this);
case SECOND: return new SecondPane();
}
return null;
}
}
public class MainPane extends JPanel {
private WindowManager windowManager;
private JDesktopPane desktopPane;
public MainPane() {
setLayout(new BorderLayout());
JButton open = new JButton("Open");
desktopPane = new JDesktopPane() {
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
};
windowManager = new DesktopWindowManage(desktopPane);
add(open, BorderLayout.NORTH);
add(desktopPane);
open.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
windowManager.openWindow(WindowManager.Window.FIRST);
}
});
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.dispose();
}
}
public class FirstPane extends JPanel {
public FirstPane(WindowManager windowManager) {
setBorder(new EmptyBorder(32, 32, 32, 32));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = gbc.REMAINDER;
add(new JLabel("I am first"), gbc);
JButton showSecond = new JButton("Show second");
showSecond.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
windowManager.openWindow(WindowManager.Window.SECOND);
}
});
add(showSecond, gbc);
}
}
public class SecondPane extends JPanel {
public SecondPane() {
setBorder(new EmptyBorder(32, 32, 32, 32));
setLayout(new GridBagLayout());
add(new JLabel("I am second"));
}
}
}
But wait, there's more...
Currently, if you tap "Open" or "Show second" multiple times, you get a bunch of new windows. This may or may not be desirable, but could be easily fixed via the WindowManager, in fact, you could create different WindowManagers based on your needs, for example...
public class DesktopWindowManage implements WindowManager {
private JDesktopPane desktopPane;
private int initialX = 0;
private int initialY = 0;
private Map<Window, JInternalFrame> windowCache = new HashMap<>();
public DesktopWindowManage(JDesktopPane desktopPane) {
this.desktopPane = desktopPane;
}
public JDesktopPane getDesktopPane() {
return desktopPane;
}
#Override
public void openWindow(Window window) {
JInternalFrame frame = windowCache.get(window);
if (frame == null) {
frame = new JInternalFrame(window.name(), true, true, true, true);
frame.setContentPane(makeContentFor(window));
windowCache.put(window, frame);
frame.pack();
frame.setLocation(initialX, initialY);
frame.setVisible(true);
desktopPane.add(frame);
initialX += 20;
initialY += 20;
}
try {
frame.setSelected(true);
} catch (PropertyVetoException ex) {
}
frame.toFront();
}
protected JPanel makeContentFor(Window window) {
switch (window) {
case FIRST:
return new FirstPane(this);
case SECOND:
return new SecondPane();
}
return null;
}
}
JTextField, JSlider, JComboBox, etc added to a JComponent are not displayed in the JFrame containing the JComponent. It seems only drawing by the Graphics parameter allows painting. The included test program compares using JPanel to JComponent in my efforts to discover how to display components added to a JComponent. Is there any way to get such components displayed?
public class TestPaints {
public static void main(String[] args) {
new TestPaints();
}
JTextField _text1;
JLabel _label1 = new JLabel("Text1");
JTextField _text2;
JLabel _label2 = new JLabel("Text2");
TestPaints() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Paint a Widget");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(3, 2));
GridBagConstraints grid = new GridBagConstraints();
frame.add(new JLabel("TextField in JComponent "));
grid.gridx = 2;
frame.add(new JLabel("TextField in JPanel"), grid);
grid.gridy = 2;
grid.gridx = 1;
frame.add(new TestJComponent(), grid);
grid.gridx = 2;
frame.add(new TestJPanel(), grid);
grid.gridy = 3;
grid.gridx = 1;
/* tabbing between the two TextFields shows that keystrokes are seen */
frame.add(_label1, grid);
grid.gridx = 2;
frame.add(_label2, grid);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestJComponent extends JComponent {
public TestJComponent() {
setPreferredSize(new Dimension(100, 30));
_text1 = new JTextField(6);
_text1.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
_label1.setText(_text1.getText());
_label1.repaint();
}
});
_text1.setOpaque(true);
_text1.setVisible(true);
add(_text1);
/* This doesn't work
JPanel panel = new JPanel();
panel.add(_text1);
add(panel); */
setOpaque(true);
setVisible(true);
setBackground(Color.green);
}
public void paint(Graphics g) {
super.paint(g); // did not do background. Rectangle r = g.getClipBounds(); // needs this
g.setColor(getBackground());
g.fillRect(r.x, r.y, r.width, r.height);
/* Variations such as these don't work */
_text1.setOpaque(true);
_text1.setVisible(true);
_text1.paintComponents(g);
}
}
class TestJPanel extends JPanel {
TestJPanel() {
_text2 = new JTextField(6);
_text2.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
_label2.setText(_text2.getText());
_label2.repaint();
}
});
add(_text2);
setBackground(Color.blue);
}
}
}
Edit: you need to give your JComponent a layout such as FlowLayout for components to show properly since it does not have a default layout like JPanel has. So add setLayout(new FlowLayout()) into your JComponent's constructor
You have:
frame.setLayout(new GridLayout(3, 2));
and then try to add components to the JFrame's contentPane using GridBagConstraints, and this doesn't make sense. If you want to use these constraints, then the container needs to use GridBagLayout, not GridLayout.
Also this is dangerous code:
public void paint(Graphics g) {
super.paint(g); // did not do background. Rectangle r = g.getClipBounds(); // needs this
g.setColor(getBackground());
g.fillRect(r.x, r.y, r.width, r.height);
/* Variations such as these don't work */
_text1.setOpaque(true);
_text1.setVisible(true);
_text1.paintComponents(g);
}
You should be overriding JComponent's paintComponent method, not its paint method (call super.paintComponent) and should not be setting component visibility or calling a component's paintComponents method directly within any painting method.
Another issue: don't use KeyListeners within Swing text components but rather add a DocumentListener to the component's Document. Otherwise you risk breaking some of the functionality of the text component, and also your listener won't work for copy/paste, while the DocumentListener will.
And another issue, your main issue: you need to give the JComponent a layout. It does not default to FlowLayout like a JPanel does. This is why the added components are not showing within it.
For example:
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
public class TestPaints2 {
private JTextField textField1 = new JTextField(8);
private JTextField textField2 = new JTextField(8);
private JLabel label1 = new JLabel("Text1");
private JLabel label2 = new JLabel("Text2");
public TestPaints2() {
textField1.getDocument().addDocumentListener(new MyDocListener(label1));
textField2.getDocument().addDocumentListener(new MyDocListener(label2));
TestJComponent2 jComponent = new TestJComponent2();
jComponent.add(textField1);
TestJPanel2 jPanel = new TestJPanel2();
jPanel.add(textField2);
JPanel mainPanel = new JPanel(new GridLayout(0, 2));
mainPanel.add(new JLabel("JComponent"));
mainPanel.add(new JLabel("JPanel"));
mainPanel.add(jComponent);
mainPanel.add(jPanel);
mainPanel.add(label1);
mainPanel.add(label2);
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private class MyDocListener implements DocumentListener {
private JLabel label;
public MyDocListener(JLabel label) {
this.label = label;
}
#Override
public void changedUpdate(DocumentEvent e) {
updateLabel(e);
}
#Override
public void insertUpdate(DocumentEvent e) {
updateLabel(e);
}
#Override
public void removeUpdate(DocumentEvent e) {
updateLabel(e);
}
private void updateLabel(DocumentEvent e) {
Document doc = e.getDocument();
int offset = doc.getLength();
try {
String text = doc.getText(0, offset);
label.setText(text);
} catch (BadLocationException e1) {
e1.printStackTrace();
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new TestPaints2());
}
}
class TestJComponent2 extends JComponent {
private static final Color BG = Color.GREEN;
private static final int GAP = 5;
public TestJComponent2() {
setOpaque(true);
setBackground(BG);
setLayout(new FlowLayout());
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
}
}
class TestJPanel2 extends JPanel {
private static final Color BG = Color.BLUE;
private static final int GAP = 5;
public TestJPanel2() {
setBackground(BG);
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
}
}
I have 4 panels which are added to a frame.
JFrame is set to GridLayout
setLayout(new GridLayout(2, 2));
add(panel1);
add(panel2);
add(panel3);
add(panel4);
When I click on a panel, I want this panel is zoom out and fit to frame's size.
getContentPane().removeAll();
setLayout(new BorderLayout());
panel1.setPreferredSize(new Dimension(getWidth(), getHeight()));
add(panel1, BorderLayout.CENTER);
revalidate();
repaint();
But It didn't work. I think that I cannot set BorderLayout for this frame, it is still GridLayout.
How can I repair it? Thanks
When I click on a panel, I want this panel is zoom out and fit to frame's size.
to use CardLayout
direct answer to the question
.
.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
public class SwitchLayoutManager {
private JFrame frame = new JFrame();
private JPanel panel1 = new JPanel() {
private static final long serialVersionUID = 1L;
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 50);
}
#Override
public Border getBorder() {
return new LineBorder(Color.BLACK, 1);
}
};
private JPanel panel2 = new JPanel() {
private static final long serialVersionUID = 1L;
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 50);
}
#Override
public Border getBorder() {
return new LineBorder(Color.RED, 1);
}
};
private JPanel panel3 = new JPanel() {
private static final long serialVersionUID = 1L;
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 50);
}
#Override
public Border getBorder() {
return new LineBorder(Color.BLUE, 1);
}
};
private JPanel panel4 = new JPanel() {
private static final long serialVersionUID = 1L;
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 50);
}
#Override
public Border getBorder() {
return new LineBorder(Color.ORANGE, 1);
}
};
private JPanel panel5 = new JPanel() {
private static final long serialVersionUID = 1L;
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
public Border getBorder() {
return new LineBorder(Color.GREEN, 1);
}
};
private GridLayout gridLayout = new GridLayout(2, 2);
private BorderLayout borderLayout = new BorderLayout();
public SwitchLayoutManager() {
frame.setLayout(gridLayout);
frame.add(panel1);
frame.add(panel2);
frame.add(panel3);
frame.add(panel4);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
Timer t = new Timer(2500, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (frame.getContentPane().getLayout() == borderLayout) {
frame.getContentPane().removeAll();
frame.setLayout(gridLayout);
frame.add(panel1);
frame.add(panel2);
frame.add(panel3);
frame.add(panel4);
frame.pack();
//frame.revalidate();
//frame.repaint();
} else if (frame.getContentPane().getLayout() == gridLayout) {
frame.getContentPane().removeAll();
frame.setLayout(borderLayout);
frame.add(panel5);
frame.pack();
//frame.revalidate();
//frame.repaint();
}
}
});
t.setInitialDelay(2500);
t.setRepeats(true);
t.start();
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new SwitchLayoutManager();
}
});
}
}
Scaled back a sample I found to test working with JPanel and JLabel.
A new TransferHandler object is created for the createTransferable() call for both JPanel and JLabel.
Since there is no setDraggable method so I included the exportAsDrag (which is what I think is required if the object doesn't have the setDraggable method).
Although createTransferable() returns null and won't really do anything I should at least get the println executed, but the code doesn't seem to enter that section which means neither the panel or label is seen as a draggable object.
What is the missing step to get this to be seen as a draggable object.
And if you have a panel with a bunch of labels is it recommended to make the panel draggable and sort out which label or make each individual label draggable?
import java.awt.*;
import java.awt.datatransfer.Transferable;
import javax.swing.*;
import java.awt.event.InputEvent;
public class DnDTransferableTest {
public static void main(String[] args) {
new DnDTransferableTest();
}
public DnDTransferableTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
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 label1;
private JLabel label2;
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weighty = 1;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.BOTH;
label1 = new JLabel("Drag Me.");
add(label1, gbc);
label2 = new JLabel("Drag Me too.");
gbc.gridx++;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.NONE;
add(label2, gbc);
setTransferHandler(new TransferHandler()
{
#Override
public Transferable createTransferable(final JComponent c)
{
System.out.println("Inside Panel : createTransferable");
return null;
}
#Override
public int getSourceActions(final JComponent c)
{
System.out.println("Inside Panel : getSourceActions()");
return COPY;
}
#Override
public void exportAsDrag(final JComponent comp, final InputEvent e, final int action)
{
System.out.println("Inside Panel : getSourceActions()");
super.exportAsDrag(comp, e, action);
}
});
label1.setTransferHandler(new TransferHandler()
{
#Override
public Transferable createTransferable(final JComponent c)
{
System.out.println("Inside Label : createTransferable");
return null;
}
#Override
public int getSourceActions(final JComponent c)
{
System.out.println("Inside Label : getSourceActions()");
return COPY;
}
#Override
public void exportAsDrag(final JComponent comp, final InputEvent e, final int action)
{
System.out.println("Inside Label : getSourceActions()");
super.exportAsDrag(comp, e, action);
}
});
}
}
}
I think that you will need a MouseListener to allow the JLabel to accept a drag gesture since it does not have a setDragEnabled(...) method.
To use a MouseListener with your DnD:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.TransferHandler;
public class DnDTransferableTest {
public static void main(String[] args) {
new DnDTransferableTest();
}
public DnDTransferableTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
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 label3;
private JTextField textField = new JTextField(15);
public TestPane() {
label3 = new JLabel("Fubars Rule!");
add(label3);
add(Box.createHorizontalStrut(35));
add(textField);
label3.setTransferHandler(new TransferHandler("text"));
label3.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent mEvt) {
JComponent component = (JComponent) mEvt.getSource();
TransferHandler tHandler = component.getTransferHandler();
tHandler.exportAsDrag(component, mEvt, TransferHandler.COPY);
}
});
}
}
}
I'm trying to set the height of a JTextField. At present its the full size of the displayed JFrame. Any ideas how I set the height to 50?
Edit: Here is the amended code along with screenshot thanks!
public class Display extends JFrame {
private DrawCanvas canvas;
private JTextField Altitude;
private JTextField TASpeed;
private JLabel altButton;
private int countA = 0;
private int countS = 0;
private int Bcount1 = 0;
public String Ccount = Integer.toString(Bcount1);
public Display() {
canvas = new DrawCanvas();
canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
canvas.setLayout(new BorderLayout());
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
cp.add(canvas, BorderLayout.LINE_START);
//here are the 2 side fields![enter image description here][2]
Altitude = new JTextField("0", 5);
Altitude.setHorizontalAlignment(JTextField.CENTER);
Altitude.setEditable(false);
Altitude.setOpaque(false);
Altitude.setFont(Altitude.getFont().deriveFont(25f));
TASpeed = new JTextField("0", 5);
TASpeed.setHorizontalAlignment(JTextField.CENTER);
TASpeed.setEditable(false);
TASpeed.setOpaque(false);
TASpeed.setFont(Altitude.getFont().deriveFont(25f));
altButton = new JLabel();
altButton.setText(Ccount);
canvas.add(altButton, BorderLayout.SOUTH);
canvas.add(Altitude, BorderLayout.LINE_END);
canvas.add(TASpeed, BorderLayout.LINE_START);
canvas.add(new JLabel(Ccount), BorderLayout.SOUTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("FLIGHT DISPLAY");
pack();
setVisible(true);
requestFocus();
}
class DrawCanvas extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
setBackground(CANVAS_BACKGROUND);
g.setColor(GROUND_COLOR);
g.drawString(Ccount, 100, 100);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Display();
}
});
}
}
As #kleopatra correctly comments, the JTextField can calculate it's own preferred size based on the platform designer's choice of Font. This example changes the size.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
/** #see http://stackoverflow.com/a/14734937/230513 */
public class Test {
private void display() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTextField tfCount = new JTextField("42", 8);
tfCount.setHorizontalAlignment(JTextField.CENTER);
tfCount.setFont(tfCount.getFont().deriveFont(50f));
f.add(tfCount, BorderLayout.NORTH);
f.add(new JPanel() { //placeholder
#Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
}, BorderLayout.CENTER);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Test().display();
}
});
}
}