Java swing Drag&Drop using many transferhandlers on layers - java

I need to handle the transfer of an object where the drop area consists of one JPanel, which has its own transferhandler, and a JLabel which also has its own transferhandler. The label is inside the panel so when I drop something on the label I want the both transferhandlers to be triggered. Is this possible?
This is a test code that I have made to explain the situation:
public static void main(String[] args) {
JFrame frame = new JFrame("JFrame Example");
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(1 ,2));
JTextField text = new JTextField("This is a text to drag!");
JPanel dropPanel = new JPanel();
JLabel dropLabel = new JLabel("Drop here");
text.setSize(30, 10);
text.setDragEnabled(true);
dropPanel.setBackground(Color.green);
dropPanel.setTransferHandler(new TransferHandler(){
#Override
public boolean importData(JComponent comp, Transferable t) {
System.out.println("Dropped on panel");
return true;
}
public boolean canImport(TransferSupport support) {
return true;
}
});
dropLabel.setTransferHandler(new TransferHandler(){
#Override
public boolean importData(JComponent comp, Transferable t) {
System.out.println("Dropped on label");
return true;
}
public boolean canImport(TransferSupport support) {
return true;
}
});
dropPanel.add(dropLabel);
panel.add(text);
panel.add(dropPanel, BorderLayout.LINE_END);
frame.add(panel);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
Thanks in advance!

Related

java communication between 2 JFrames

I'm getting an AWT-EventQueue-0 Null Pointer Exception in the below code and I can't get to fix it.
I want to have a main frame, from which by pressing a button
I open a second frame, where I have the option to create new players,
which would show up in the main frame.
I passed the references to the constructors, but I still keep getting the error.
I would be very happy for some help, thanks!
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new App();
}
});
}
}
public class App extends JFrame {
private MainPanel mainPanel;
private SecondPanel secondPanel;
public App() {
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800, 600);
secondPanel = new SecondPanel(mainPanel);
mainPanel = new MainPanel(secondPanel);
add(mainPanel);
}
}
public class MainPanel extends JPanel {
private JTextArea textArea;
private JScrollPane scrollPane;
private JButton options;
public MainPanel(SecondPanel secondPanel) {
textArea = new JTextArea();
textArea.setColumns(20);
textArea.setRows(5);
textArea.setSize(300, 300);
textArea.setVisible(true);
textArea.setEditable(false);
scrollPane = new JScrollPane(textArea);
scrollPane.setSize(new Dimension(400, 400));
options = new JButton("Options");
options.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
secondPanel.setVisible(true);
}
});
add(scrollPane);
add(options);
}
public JTextArea getTextArea() {
return textArea;
}
public void setTextArea(JTextArea textArea) {
this.textArea = textArea;
}
}
public class SecondPanel extends JFrame {
private JButton create, remove;
private JPanel panel;
public SecondPanel(MainPanel mainPanel) {
setVisible(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 400);
panel = new JPanel();
panel.setLayout(new BorderLayout());
create = new JButton("create");
create.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
mainPanel.getTextArea().append("New Player Created");
}
});
remove = new JButton("remove");
remove.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
mp.getTextArea().setText("Player removed");
}
});
add(panel);
panel.add(create, BorderLayout.EAST);
panel.add(remove, BorderLayout.WEST);
}
}
Well, it has to be "null", because you don't initialise your MainPanel before you hand it over to the secondPanel.
Instead, make an own method for setting the MainPanel on the secondPanel and to set the secondPanel on the MainPanel.
I see that you need the secondPanel for instance in your constructor to set an ActionListener. Do that in your "setSecondPanel(SecondPanel sPanel)"-Method which, as I mentioned before, you should create.

It is posible to expand a JTextArea or JTextPane by clicking on it?

i'm trying to do an aplication but i don't know if is posible to do something like this, for example:
So the rectangle is the JTextArea (or JTextPane) and it has a fixed zise, that's why are the suspension points, but when i clikc on it like this:
we got the expansion of JTextArea(or JTextPane), but when the focus is losted it will come back at the begining:
The text can be anything , so when the text is too long, automatically add "..." at the end
Another option is to use CardLayout and the focusable JLabel instead of JTextField in order to use the default JLabel truncate feature:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TextAreaExpandTest {
private static final String TEXT =
"The text can be anything, so when the text is too long," +
" automatically add '...' at the end.";
public JComponent makeUI() {
CardLayout cardLayout = new CardLayout();
JPanel cp = new JPanel(cardLayout);
JTextArea textArea = new JTextArea(TEXT, 5, 10) {
#Override public void updateUI() {
super.updateUI();
setLineWrap(true);
setWrapStyleWord(true);
setMargin(new Insets(1, 1, 1, 1));
}
};
JLabel textField = new JLabel(" ") {
#Override public void updateUI() {
super.updateUI();
setOpaque(true);
setFocusable(true);
setBackground(UIManager.getColor("TextField.background"));
setForeground(UIManager.getColor("TextField.foreground"));
setBorder(UIManager.getBorder("TextField.border"));
}
};
textArea.addFocusListener(new FocusAdapter() {
#Override public void focusLost(FocusEvent e) {
String text = textArea.getText();
textField.setText(text.isEmpty() ? " " : text);
cardLayout.show(cp, "TextField");
}
});
textField.addFocusListener(new FocusAdapter() {
#Override public void focusGained(FocusEvent e) {
cardLayout.show(cp, "TextArea");
textArea.requestFocusInWindow();
}
});
textField.addMouseListener(new MouseAdapter() {
#Override public void mousePressed(MouseEvent e) {
cardLayout.show(cp, "TextArea");
textArea.requestFocusInWindow();
}
});
JPanel panel = new JPanel(new BorderLayout());
panel.add(textField, BorderLayout.NORTH);
JScrollPane scroll = new JScrollPane(
textArea,
ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
cp.add(panel, "TextField");
cp.add(scroll, "TextArea");
JPanel p = new JPanel(new BorderLayout());
p.setBorder(BorderFactory.createEmptyBorder(32, 32, 32, 32));
p.add(cp, BorderLayout.NORTH);
p.add(new JButton("focus dummy"), BorderLayout.SOUTH);
return p;
}
// //TEST: JTextArea"setRows(...)
// public JComponent makeUI2() {
// JPanel p = new JPanel(new BorderLayout());
// JTextArea textArea = new JTextArea("", 1, 10);
// textArea.setLineWrap(true);
// textArea.addFocusListener(new FocusListener() {
// #Override public void focusGained(FocusEvent e) {
// JTextArea ta = (JTextArea) e.getComponent();
// ta.setRows(8);
// p.revalidate();
// }
// #Override public void focusLost(FocusEvent e) {
// JTextArea ta = (JTextArea) e.getComponent();
// ta.setRows(1);
// p.revalidate();
// }
// });
// JScrollPane scroll = new JScrollPane(
// textArea,
// ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
// ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
// p.add(scroll, BorderLayout.NORTH);
// p.add(new JButton("focus dummy"), BorderLayout.SOUTH);
// p.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
// return p;
// }
public static void main(String... args) {
EventQueue.invokeLater(() -> {
UIManager.put("swing.boldMetal", Boolean.FALSE);
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new TextAreaExpandTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
Use a JPanel to add and remove JTextField and JTextArea with FocusListener
For one line input use JTextField and to add "..." you need to implement KeyListener interface.
Use a global flag that will set whenever you GainFocus on JTextField. A thread will check for this flag and if it is set then it will remove the JTextField object from JPanel and add JTextArea with saved String.
OR
You can implement FocusListner to JPanel instead of more complicated thread thing.
Everything depends on the layout you are using. What I would do would be to use a layout the respects the preferredSize of its components. Then I would change the preferredSize of the JTextPane given a Boolean parameter (expanded or not expanded).
When I say change the preferredSize, I mean override the getPreferredSize method.

JScrollPane does not work on JPanel

I have a frame that contains a mainPanel. This last will add other commandPanels (each one contains a button and a textField) Dynamically. the problem is that the JScrollPane does not appear to let me use the unseen commandPanels even if the mainPanel is full.
The below picture shows my case.
To initialize the window I wrote below code:
frame = new JFrame();
frame.setBounds(100, 100, 962, 639);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
mainPanel = new JPanel();
mainPanel.setBounds(264, 6, 692, 500);
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
scroll = new JScrollPane();
scroll.getViewport().add(mainPanel);
frame.getContentPane().add(scroll);
and the method that add dynamically the new commandPanels is:
public void loadCommandPanel(String commandName)
{
CommandPanel newCommandPanel = new CommandPanel();
newCommandPanel.getCommandBtn().setText(commandName);
mainPanel.add(newCommandPanel);
scroll.getViewport().add( newCommandPanel );
mainPanel.add( scroll, BorderLayout.EAST);
frame.add( mainPanel);
...
}
Any help to get the scrollPane, will be much more than appreciated.
scroll.getViewport().add(mainPanel); is not how you use JViewport or JScrollPane; instead you should using something like this:
scroll.getViewport().setView(newCommandPanel);
or
scroll.setViewportView(newCommandPanel);
Take a look at How to Use Scroll Panes for more details.
Note also, this doesn't makes sense:
CommandPanel newCommandPanel = new CommandPanel();
newCommandPanel.getCommandBtn().setText(commandName);
mainPanel.add(newCommandPanel);
scroll.getViewport().add( newCommandPanel );
You add newCommandPanel to mainPanel, then promptly add it to another container (albeit incorrectly).
A component can only reside on a single parent; the moment you add it to another container, it is automatically removed from the previous container.
I have made some changes and it works perfectly now. For those who want the same thing here's my code:
import ...
public class mainUserInterface {
private JFrame frame;
private JPanel mainPanel;
private JPanel commandsPanel;
private JScrollPane commandsScrollPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
mainUserInterface window = new mainUserInterface();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public mainUserInterface() {
initialize();
}
private void initialize() {
frame = new JFrame("CommandsExecutor");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(1000, 700));
mainPanel = new JPanel(new BorderLayout(5,5));
mainPanel.setBorder( new TitledBorder("") );
commandsPanel = new JPanel();
commandsPanel.setLayout(new BoxLayout(commandsPanel, BoxLayout.Y_AXIS));
for(int i=0; i<15;i++){
commandsPanel.add(new CommandPanel());
}
commandsScrollPane = new JScrollPane(commandsPanel);
mainPanel.add(commandsScrollPane,BorderLayout.CENTER);
frame.setContentPane(mainPanel);
frame.pack();
frame.setVisible(true);
}
}
and Here's the commandPanel class:
import ...
public class CommandPanel extends JPanel {
private JTextField commandResult;
private JButton commandBtn;
public CommandPanel()
{
this.setLayout( new BorderLayout(10,10));
this.setBorder( new TitledBorder("Command:") );
this.setMaximumSize(new Dimension(692,60));
this.setMinimumSize(new Dimension(692,60));
commandBtn = new JButton("Execute");
commandBtn.setMaximumSize(new Dimension(137, 34));
commandBtn.setMinimumSize(new Dimension(137, 34));
this.add(commandBtn, BorderLayout.WEST);
commandResult = new JTextField();
commandResult.setMaximumSize(new Dimension(518, 34));
commandResult.setMinimumSize(new Dimension(518, 34));
this.add(commandResult, BorderLayout.CENTER);
}
public JTextField getCommandResult() {
return commandResult;
}
public JButton getCommandBtn() {
return commandBtn;
}
public void setCommandResult(JTextField commandResult) {
this.commandResult = commandResult;
}
public void setCommandBtn(JButton commandBtn) {
this.commandBtn = commandBtn;
}
}
Thanks for all who answered my question, it really helped.

How to add checkbox to the right side of jButton?

I want to create a button with checkbox in the right side of it.
i tried this but checkbox stays on the center of button on the top of button label text.
Any ideas welkom.
thanks in advance:
public class MainTest extends JPanel {
JButton button;
JPanel panel;
public MainTest() {
createComponents();
layoutComponents();
}
public void createComponents() {
// attempting to add checkbox to button
button = new JButton("Print with Edge");
JCheckBox checkBox = new JCheckBox();
jcb.setHorizontalAlignment(SwingConstants.RIGHT);
button.add(checkBox,new BorderLayout());
panel = new JPanel(new BorderLayout());
}
public void layoutComponents() {
panel.add(button,BorderLayout.SOUTH);
add(panel);
}
public static void main(String[] args) {
MainTest demo = new MainTest();
JFrame frame = new JFrame();
Container cp = frame.getContentPane();
cp.add(demo);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setLocation(500, 500);
frame.setVisible(true);
}
}
You can wrap a JCheckBox inside a JPanel and make the JPanel look like a button. For example:
public class Test {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(new Dimension(100, 100));
JCheckBox button = new JCheckBox();
final JPanel buttonWrapper = new JPanel();
buttonWrapper.add(new JLabel("Button Text"));
buttonWrapper.add(button);
buttonWrapper.setBorder(BorderFactory.createRaisedBevelBorder());
buttonWrapper.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent me) {
buttonWrapper.setBorder(BorderFactory.createEtchedBorder());
}
#Override
public void mouseReleased(MouseEvent me) {
buttonWrapper.setBorder(BorderFactory.createRaisedBevelBorder());
}
#Override
public void mouseClicked(MouseEvent me) {
System.out.println("mouse clicked");
}
});
JPanel mainPanel = new JPanel();
mainPanel.add(buttonWrapper);
frame.getContentPane().add(mainPanel);
frame.setVisible(true);
}
}
I want to create a button with checkbox in the right side of it.
Maybe you just want the checkbox on the right side of the text?
If so you can do:
JCheckBox cb = new JCheckBox("Print with Edge");
cb.setHorizontalTextPosition(SwingConstants.LEADING);

How to use 2 panels in applet?

I am trying to work out how to navigate across multiple panels in swing. I would like to do this by using the CardLayout as opposed to using glass panels as from what I have read it seems that this is the correct tool for this job (however, feel free to correct me if you know otherwise). I have written a test case which almost achieves this but falls short on 2 fronts. It uses the depreciated "show()" method and furthermore after it switches to the second card the buttons from card1 begin to mysteriously float through to the surface again!
public class test extends JPanel implements ActionListener{
final static int extraWindowWidth = 100;
JButton jbtnOne = new JButton("Button 1");
JPanel cardPanel = new JPanel(new CardLayout());
JPanel card1 = new JPanel();
JPanel card2 = new JPanel();
public void addComponentToPane(Container pane) {
//Create the "cards".
JPanel card1 = new JPanel() {
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
size.width += extraWindowWidth;
return size;
}
};
card1.add(jbtnOne);
card1.add(new JButton("Button 2"));
card1.add(new JButton("Button 3"));
card2.add(new JTextField("TextField", 20));
cardPanel.add(card1, "card1");
cardPanel.add(card2, "card2");
pane.add(cardPanel, BorderLayout.CENTER);
jbtnOne.addActionListener(this);
}
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("TabDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
test demo = new test();
demo.addComponentToPane(frame.getContentPane());
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getSource() == jbtnOne){
System.out.println("HERE");
card2.show();
}
}
}
The CardLayout is managing the components so you will need to call show on the CardLayout instead of JPanel#show:
CardLayout cardLayout = (CardLayout) cardPanel.getLayout();
cardLayout.show(cardPanel, "card2");
Alternatively, when switching card components, you could also use
cardLayout.next(cardPanel);

Categories

Resources