This is the example i got from http://djproject.sourceforge.net/ns/documentation/Snippets.html with a little bit modification.
package View;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import chrriis.common.UIUtils;
import chrriis.dj.nativeswing.swtimpl.NativeInterface;
import chrriis.dj.nativeswing.swtimpl.components.JWebBrowser;
/**
* #author Christopher Deckers
*/
public class GoogleMaps extends JPanel {
public GoogleMaps() {
JPanel webBrowserPanel = new JPanel(new BorderLayout());
webBrowserPanel.setBorder(BorderFactory.createTitledBorder("Native Web Browser component"));
final JWebBrowser webBrowser = new JWebBrowser();
webBrowser.navigate("http://www.google.com");
webBrowserPanel.add(webBrowser, BorderLayout.CENTER);
add(webBrowserPanel, BorderLayout.CENTER);
// Create an additional bar allowing to show/hide the menu bar of the web browser.
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 4, 4));
JCheckBox menuBarCheckBox = new JCheckBox("Menu Bar", webBrowser.isMenuBarVisible());
menuBarCheckBox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
webBrowser.setMenuBarVisible(e.getStateChange() == ItemEvent.SELECTED);
}
});
buttonPanel.add(menuBarCheckBox);
add(buttonPanel, BorderLayout.SOUTH);
}
}
and then in another JFrame, I am trying to open this browser by clicking a button:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
GoogleMaps maps = new GoogleMaps();
UIUtils.setPreferredLookAndFeel();
NativeInterface.open();
JFrame frame = new JFrame("DJ Native Swing Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(maps, BorderLayout.CENTER);
frame.setSize(800, 600);
frame.setLocationByPlatform(true);
frame.setVisible(true);
NativeInterface.runEventPump();
}
But then it freeze my GUI. What should I do in this case?
Any pointers will help
NativeInterface.runEventPump() function is a blocking one. It should be run in another thread.
In your case it could be solved like this:
new Thread(new Runnable() {
#Override
public void run() {
if (!NativeInterface.isEventPumpRunning())
NativeInterface.runEventPump();
}
}).start();
Related
I want to add a JPanel to a JLayeredPane when the user clicks enter, but the JPanel is not showing up.
If i add the JPanel to the JLayeredPane in the JFrame's constructor, everything is working correctly.
What do i have to do, that the JPanel is showing up, when the user clicks 'enter'?
Here's the code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class Test extends javax.swing.JFrame {
public static void main(String[] args) {
Test test = new Test();
test.setSize(800, 500);
test.setVisible(true);
}
public Test() {
setLayout(new BorderLayout());
//LayeredPane on JFrame
JLayeredPane jlp = new JLayeredPane();
jlp.setLayout(new BorderLayout());
this.add(jlp, BorderLayout.CENTER);
//Adds a JPanel to the North
JPanel jPNorth = new JPanel();
jPNorth.setBackground(Color.RED);
jlp.add(jPNorth, BorderLayout.NORTH, JLayeredPane.DEFAULT_LAYER);
//Adds Enter Keybinding
InputMap key_input_map = jlp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap key_action_map = jlp.getActionMap();
key_input_map.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false), "add_jpanel");
key_action_map.put("add_jpanel", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
JPanel jPSouth = new JPanel();
jPSouth.setBackground(Color.YELLOW);
jlp.add(jPSouth, BorderLayout.SOUTH, JLayeredPane.DEFAULT_LAYER);
System.out.println("enter");
}
});
}
}
Thanks,
Jumagoro
You did everything correct, the solution is very simple. When you dynamically add swing Components to each other, you must to use component.repaint(); and component.revalidate(); to redraw the elements. Add the two commands after everything is added. So your actionPerformed method should be changed to the following:
public void actionPerformed(ActionEvent e) {
JPanel jPSouth = new JPanel();
jPSouth.setBackground(Color.YELLOW);
jlp.add(jPSouth, BorderLayout.SOUTH, JLayeredPane.DEFAULT_LAYER);
//Need these to here!
jlp.repaint();
jlp.revalidate();
System.out.println("enter");
}
My question is about layout in Java Swing.
I want to make a screen like shown below. I saw this video on youtube and made a gif of the part I want.
I want 2 panels and a button like this:
When i clicked the button the JPanel will be hidden and JTable's width will be 100% like html/css like this; (And when button clicked again JPanel will be shown etc..)
How can I do this? Which layout should I use?
There is more than one way to do it, but here's an example that uses BorderLayout as the main layout, and places the button in a left aligning FlowLayout:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
public class LayoutDemo {
private LayoutDemo() {
JFrame frame = new JFrame("Demo");
frame.setLocationByPlatform(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel buttonHolder = new JPanel(new FlowLayout(FlowLayout.LEADING));
frame.add(buttonHolder, BorderLayout.NORTH);
JButton button = new JButton("Toggle visibility");
buttonHolder.add(button);
final JPanel left = new JPanel();
left.setPreferredSize(new Dimension(100, 200));
left.setBackground(Color.BLUE);
frame.add(left, BorderLayout.LINE_START);
JLabel table = new JLabel("This pretends to be a table", SwingConstants.CENTER);
table.setPreferredSize(new Dimension(400, 200));
frame.add(table);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
left.setVisible(!left.isVisible());
}
});
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new LayoutDemo();
}
});
}
}
I used setPreferredSize() to give the components some reasonable default size, but usually it should be automatically calculated by the layout manager from the sizes of the child components, or in case of a custom component, you should override getPreferredSize() return what is appropriate for the component.
The result looks like:
I have a simple web browser coded in java.
As you may know, the application can't display much.
For instance, google. It won't display the page the right way.
But that's not the problem I want to solve..
The problem is that it won't display pages like AGAR.io (don't misspell the "agar" word.. There's a Jeff the Killer jumpscare if you open this page : agor.io. So be careful :))
Here's the java code of the simple web browser:
package Gui;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.IDN;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
#SuppressWarnings("serial")
public class Frame extends JFrame implements HyperlinkListener {
private JTextField txtURL= new JTextField("");
JEditorPane ep = new JEditorPane();
private JLabel lblStatus= new JLabel(" ");
public Frame() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel pnlURL = new JPanel();
pnlURL.setLayout(new BorderLayout());
pnlURL.add(new JLabel("URL: "), BorderLayout.WEST);
pnlURL.add(txtURL, BorderLayout.CENTER);
getContentPane().add(pnlURL, BorderLayout.NORTH);
getContentPane().add( ep, BorderLayout.CENTER);
getContentPane().add(lblStatus, BorderLayout.SOUTH);
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
try {
String url = ae.getActionCommand().toLowerCase();
if (url.startsWith("http://"))
url = url.substring(7);
ep.setPage("http://" + IDN.toASCII(url));
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(Frame.this, "Browser problem: " + e.getMessage());
}
}
};
txtURL.addActionListener(al);
setSize(300, 300);
setVisible(true);
}
public void hyperlinkUpdate(HyperlinkEvent hle) {
HyperlinkEvent.EventType evtype = hle.getEventType();
if (evtype == HyperlinkEvent.EventType.ENTERED)
lblStatus.setText(hle.getURL().toString());
else if (evtype == HyperlinkEvent.EventType.EXITED)
lblStatus.setText(" ");
}
public static void main(String[] args) {
new Frame();
}
}
But the program can't display pages such as agar.io.
Agar.io is a page with a simple game that seems to not use flashplayer..
Is there a way of making it possible?
Accordion can be downloaded here - http://www.javaswingcomponents.com/product/accordion
Here is a sample output of an accordion. I want to remove the numbers on the right side of the tab. How can I do it? Thanks!
Here is the code of the sample:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import com.javaswingcomponents.accordion.JSCAccordion;
import com.javaswingcomponents.accordion.TabOrientation;
public class SampleAccordion extends JPanel {
static JFrame frame;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
SampleAccordion codeExample = new SampleAccordion();
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container panel = frame.getContentPane();
panel.setLayout(new BorderLayout());
panel.add(codeExample, BorderLayout.CENTER);
frame.pack();
frame.setSize(500, 300);
frame.setVisible(true);
}
});
}
public SampleAccordion() {
JSCAccordion accordion = new JSCAccordion();
JPanel transparentPanel = new JPanel();
transparentPanel.setOpaque(false);
transparentPanel.setBackground(Color.GRAY);
JPanel opaquePanel = new JPanel();
opaquePanel.setOpaque(true);
opaquePanel.setBackground(Color.GRAY);
accordion.addTab("Tab 1", new JLabel("help me remove 1"));
accordion.addTab("Tab 2", new JLabel("help me remove 2"));
accordion.setTabOrientation(TabOrientation.VERTICAL);
setLayout(new GridLayout(1, 1, 30, 30));
add(accordion);
}
}
You can specify whether you want to see the tab index:
accordion.setTabOrientation(TabOrientation.VERTICAL);
((FormattedTabRenderer) accordion.getTabRenderer()).setShowIndex(false);
(The first line is already in the sample code and is only included as a reference.)
It looks like the accordion supports three pluggable look & feels: basic, steel, and dark steel. I'm not sure whether the tab renderer can be cast to the FormattedTabRenderer abstract class for all PLAFs, but it seems to work fine for steel.
I have a show button to show a JTable on click but the table is not visible.
Note: when I remove the JScrollPane the code works properly but the header of the table is not shown, so any help please to make this code work properly without removing the JScrollPane
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
public class Training extends JFrame {
public Training() {
getContentPane().setLayout(new FlowLayout());
JTable table = new JTable();
table.setModel(new DefaultTableModel(new Object[][] { { "joe", "joe" },
{ "mickel", "mickel" }, }, new String[] { "LastName",
"FirstName" }));
final JScrollPane pane = new JScrollPane(table);
pane.setVisible(false);
getContentPane().add(pane);
JButton btn = new JButton("show");
add(btn);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
pane.setVisible(true);
}
});
}
public static void main(String[] args) {
Training app = new Training();
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.setSize(600, 600);
app.setVisible(true);
}
}
After pane.setVisible(true); add the following:
getContentPane().validate();
getContentPane().repaint();
A few things to note:
Never extends JFrame class unnecessarily, or else you might need to extend another class which is very necessary but in java a single class may not extend more than one other class (no multiple inheritance).
Always create Swing components on Event Dispatch Thread via SwingUtilities.invokeLater(Runnable r) block.
Do not use setSize(..) call JFrame#pack() before setting JFrame visible
No need for getContentPane.add(..) or getContentPane().setLayout(..), simply call add(..) or setLayout(..) on JFrame instance as these calls are fowared to the contentPane.
The problem you have is you do not refresh you frame/container after setting pane visible. I disagree with #Dan. Do not use validate() (getContentPane() is not necesarry either) rather:
revalidate();
repaint();
as revalidate() covers validate(). Also validate is used when new JComponents are added to a visible component, whereas revalidate() is used when JComponent is removed/added from a visible component.
Here is a fixed version of the code with the above implemented:
After button pressed:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
public class Training {
private JFrame frame;
public Training() {
frame = new JFrame();
frame.setLayout(new FlowLayout());
JTable table = new JTable();
table.setModel(new DefaultTableModel(new Object[][]{{"joe", "joe"},
{"mickel", "mickel"},}, new String[]{"LastName",
"FirstName"}));
final JScrollPane pane = new JScrollPane(table);
pane.setVisible(false);
frame.add(pane);
JButton btn = new JButton("show");
frame.add(btn);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
pane.setVisible(true);
frame.pack();//this is so the frame will resize after adding pane
frame.revalidate();
frame.repaint();
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Training();
}
});
}
}
UPDATE:
Also for a more reusable Layout, why not add all components to a JPanel, and add that JPanel to the JFrame, thus if you ever need to add more stuff its simple.