JScrollPane component doesn't appear - java

I am trying to add a JList to my JPanel as it is stated by the following source code but it's not working :
public class Game {
public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
DefaultListModel<String> defListPlayers = new DefaultListModel<String>();
defListPlayers.addElement("Player 1");
defListPlayers.addElement("Player 2");
JList<String> listPlayers = new JList<String>(defListPlayers);
listPlayers.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
listPlayers.setLayoutOrientation(JList.VERTICAL);
listPlayers.setVisibleRowCount(10);
JScrollPane scroller = new JScrollPane(listPlayers);
scroller.setViewportBorder(new LineBorder(Color.RED));
scroller.revalidate();
JPanel panel = new JPanel();
panel.add(scroller);
JFrame frame = new JFrame;
frame.setContentPane(panel);
frame.pack();
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().repaint();
}
}
Any idea please why and what to do?

Related

ScrollPane not showing on JLabel

When I run this program, I don't see a scrollbar on the Label. What am I missing?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Util1
{
public static void main(String[] args)
{
new Util1();
}
public Util1()
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new ExamplePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
protected class ExamplePane extends JPanel
{
public ExamplePane()
{
final JPanel panel = new JPanel(new GridBagLayout());
final JLabel message = new JLabel("<html>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello</html>");
message.setPreferredSize(new Dimension(500, 50));
JScrollPane scroller = new JScrollPane( message, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroller.setViewportView(message);
panel.add(scroller);
add(panel);
}
}
}
To see a scrollbar wrap the "message" JLabel into JPanel and then add this JPanel to JScrollPane like bellow:
public ExamplePane() {
final JPanel panel = new JPanel(new GridBagLayout());
final JLabel message = new JLabel("<html>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello<br>Hello</html>");
message.setPreferredSize(new Dimension(500, 50));
final JPanel messagePanel = new JPanel();
messagePanel.add(message);
JScrollPane scroller = new JScrollPane(messagePanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroller.setPreferredSize(new Dimension(100, 50));
panel.add(scroller);
add(panel);
}

JTabbedpane is not correctly created when moved to separate class

When intializing JTabbedpane in my main class everything works fine, but in order to don't repeat the same code over and over again I wanted to move the initialization part to separate class so I can easyli create new tabs without generating the same code again.
Unfortunately after moving the code to separate class the JTabbedpane is not created properly, because items added to list are not displayed. It looks like the JPanel is not loading as the screen under the tab is greyed (when it is working it is white).
Below is the code that works:
private void initialize() {
frmLoganalyzer = new JFrame();
frmLoganalyzer.setTitle("LogAnalyzer");
frmLoganalyzer.setBounds(100, 100, 450, 300);
frmLoganalyzer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmLoganalyzer.setExtendedState(frmLoganalyzer.getExtendedState() | JFrame.MAXIMIZED_BOTH);
JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
frmLoganalyzer.getContentPane().add(tabbedPane, BorderLayout.CENTER);
JPanel systemLogTab = new JPanel();
tabbedPane.addTab("System Log", null, systemLogTab, null);
DefaultListModel listModel = new DefaultListModel<LogSystem>();
systemLogTab.setLayout(new BorderLayout(0, 0));
JList list = new JList(listModel);
list.setCellRenderer(new CustomListCellRenderer());
list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
list.setLayoutOrientation(JList.VERTICAL);
list.setVisibleRowCount(-1);
JScrollPane listScroller = new JScrollPane(list);
listScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
listScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
systemLogTab.add(listScroller);
}
I tried to move it to look like this:
private void initialize() {
frmLoganalyzer = new JFrame();
frmLoganalyzer.setTitle("LogAnalyzer");
frmLoganalyzer.setBounds(100, 100, 450, 300);
frmLoganalyzer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmLoganalyzer.setExtendedState(frmLoganalyzer.getExtendedState() | JFrame.MAXIMIZED_BOTH);
JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
frmLoganalyzer.getContentPane().add(tabbedPane, BorderLayout.CENTER);
TabManager tabManager = new TabManager(tabbedPane);
DefaultListModel listModel = new DefaultListModel<LogSystem>();
tabManager.addTab("System Log", null, listModel);
}
And in the class for initializing the tab:
public void addTab(String tabName, Icon icon, DefaultListModel<LogSystem> listModel) {
JPanel systemLogTab = new JPanel();
tabbedPane.addTab(tabName, null, systemLogTab, null);
systemLogTab.setLayout(new BorderLayout(0, 0));
JList<LogSystem> list = new JList(listModel);
list.setCellRenderer(new CustomListCellRenderer());
list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
list.setLayoutOrientation(JList.VERTICAL);
list.setVisibleRowCount(-1);
JScrollPane listScroller = new JScrollPane(list);
listScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
listScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
systemLogTab.add(listScroller);
}
What I am doing wrong?
I deleted a lot of code not relevant to the GUI and had to change the addTab method definition because tabbedPane wasn't visible. It works fine:
public class Example {
#SuppressWarnings("serial")
private static void initialize() {
JFrame frmLoganalyzer = new JFrame();
frmLoganalyzer.setTitle("LogAnalyzer");
frmLoganalyzer.setBounds(100, 100, 450, 300);
frmLoganalyzer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTabbedPane tabbedPane = new JTabbedPane();
frmLoganalyzer.getContentPane().add(tabbedPane);
JPanel systemLogTab = new JPanel();
tabbedPane.addTab("System Log", null, systemLogTab, null);
systemLogTab.setLayout(new BorderLayout());
JList list = new JList();
JScrollPane listScroller = new JScrollPane(list);
systemLogTab.add(listScroller);
frmLoganalyzer.setVisible(true);
}
private static void initialize2() {
JFrame frmLoganalyzer = new JFrame();
frmLoganalyzer.setTitle("LogAnalyzer");
frmLoganalyzer.setBounds(100, 100, 450, 300);
frmLoganalyzer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTabbedPane tabbedPane = new JTabbedPane();
frmLoganalyzer.getContentPane().add(tabbedPane);
addTab("System Log", tabbedPane);
frmLoganalyzer.setVisible(true);
}
public static void addTab(String tabName, JTabbedPane tabbedPane) {
JPanel systemLogTab = new JPanel();
tabbedPane.addTab(tabName, null, systemLogTab, null);
systemLogTab.setLayout(new BorderLayout());
JList list = new JList();
JScrollPane listScroller = new JScrollPane(list);
systemLogTab.add(listScroller);
}
public static void main(String[] args) {
initialize(); // call initialize2() and see that it's the same
}
}

Java panel alignment

class CipherGUIFrame extends JFrame {
public CipherGUIFrame() {
super("Caesar Cipher GUI");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 600);
JTextArea area1 = new JTextArea();
JTextArea area2 = new JTextArea();
JSpinner myspinner=new JSpinner();
JPanel mainframe = new JPanel();
mainframe.setLayout(new BoxLayout(mainframe, BoxLayout.Y_AXIS));
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
JPanel p3 = new JPanel();
p1.setLayout(new BoxLayout(p1, BoxLayout.Y_AXIS));
p2.setLayout(new BoxLayout(p2, BoxLayout.Y_AXIS));
p1.setBorder(BorderFactory.createTitledBorder("Cleartext"));
p2.setBorder(BorderFactory.createTitledBorder("Spinner"));
p3.setLayout(new BoxLayout(p3, BoxLayout.Y_AXIS));
p3.setBorder(BorderFactory.createTitledBorder("Ciphertext"));
p1.add(area1);
p2.add(myspinner);
p3.add(area2);
mainframe.add(p1);
mainframe.add(p2);
mainframe.add(p3);
this.add(mainframe);
}
}
It seems that this code produces something which looks similar to this:
I am trying to tidy this up so it looks cleaner; is there a way to shrink the middle panel or to make the others bigger to make it look nicer?
Don't set the sizes of anything, but instead set the columns and rows of your JTextAreas. Don't use BoxLayout when you don't want its behaviors. Put your JTextAreas in JScrollPanes instead. And don't forget to pack() your JFrame.
import java.awt.BorderLayout;
import javax.swing.*;
public class Cipher2 extends JPanel {
public static final int ROWS = 12;
public static final int COLS = 30;
private JTextArea textArea1 = new JTextArea(ROWS, COLS);
private JTextArea textArea2 = new JTextArea(ROWS, COLS);
public Cipher2() {
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); // Box OK here
JScrollPane scroll1 = new JScrollPane(textArea1);
add(wrapComponentWithTitle(scroll1, "Fubar"), BorderLayout.PAGE_START);
add(wrapComponentWithTitle(new JSpinner(), "Spinner"), BorderLayout.CENTER);
scroll1 = new JScrollPane(textArea2);
add(wrapComponentWithTitle(scroll1, "Snafu"), BorderLayout.PAGE_END);
}
private JPanel wrapComponentWithTitle(JComponent component, String title) {
// BoxLayout NOT OK here. Use BorderLayout instead
JPanel wrapPanel = new JPanel(new BorderLayout());
wrapPanel.add(component);
wrapPanel.setBorder(BorderFactory.createTitledBorder(title));
return wrapPanel;
}
private static void createAndShowGui() {
Cipher2 mainPanel = new Cipher2();
JFrame frame = new JFrame("Foo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I figured out the answer: change Y_AXIS to X_AXIS.
<3

Java Using not extending from JFrame

I am having a hard time understanding how to write my program with out having it extend from JFrame.
I have tried removing the extends JFrame clause and and adding it into both my methods, replacing the CalculatorWhichUsesAInterface frame = new CalculatorWhichUsesAInterface(); section with JFrame frame = new JFrame(); and a few other things and nothing has worked.
How should I go about using JFrame frame = new JFrame() in my program instead of using extends JFrame?
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
class CalculatorWhichUsesAInterface extends JFrame{
JFrame frame = new JFrame();
public CalculatorWhichUsesAInterface(){
JPanel jPanelOne = new JPanel();
jPanelOne.setLayout(new GridLayout(1, 1);
jPanelOne.add(new JButton("x"));
JPanel jPanelTwo = new JPanel(new BorderLayout());
JTextField field = new JTextField();
field.setText("2141987.01235");
jPanelTwo.add(field, BorderLayout.NORTH);
jPanelTwo.add(jPanelOne, BorderLayout.CENTER);
add(jPanelTwo, BorderLayout.CENTER);
}
public static void main(String[] args){
CalculatorWhichUsesAInterface frame = new CalculatorWhichUsesAInterface();
frame.setTitle("Calculator");
frame.setSize(500, 200);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
This is actually relativly easy (sorry, but it is).
Start by extending your class from JPanel, this provides you a basic container onto which to build your interface.
Remove the JFrame frame = new JFrame(); as you're not really using it and in your main method, create a new instance of JFrame and add you component to it
class CalculatorWhichUsesAInterface extends JPanel {
public CalculatorWhichUsesAInterface(){
JPanel jPanelOne = new JPanel();
jPanelOne.setLayout(new GridLayout(1, 1);
jPanelOne.add(new JButton("x"));
JPanel jPanelTwo = new JPanel(new BorderLayout());
JTextField field = new JTextField();
field.setText("2141987.01235");
jPanelTwo.add(field, BorderLayout.NORTH);
jPanelTwo.add(jPanelOne, BorderLayout.CENTER);
add(jPanelTwo, BorderLayout.CENTER);
}
public static void main(String[] args){
EventQueue.invokeLater(new Runnable() {
public void run() {
CalculatorWhichUsesAInterface calc = new CalculatorWhichUsesAInterface();
JFrame frame = new JFrame()
frame.setTitle("Calculator");
frame.add(calc);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
This concept provides you with a flexible and re-usable component. This means that you can decide how and where the component is to be displayed. Displayed on it's own in it's own frame (as the above example does) or added to another container (such as another JPanel or even an applet)
You may also want to take a look at Initial Threads
Example two - not extending anything
class CalculatorWhichUsesAInterface {
public static void main(String[] args){
EventQueue.invokeLater(new Runnable() {
public void run() {
JPanel jPanelOne = new JPanel();
jPanelOne.setLayout(new GridLayout(1, 1);
jPanelOne.add(new JButton("x"));
JPanel jPanelTwo = new JPanel(new BorderLayout());
JTextField field = new JTextField();
field.setText("2141987.01235");
jPanelTwo.add(field, BorderLayout.NORTH);
jPanelTwo.add(jPanelOne, BorderLayout.CENTER);
JFrame frame = new JFrame()
frame.setTitle("Calculator");
frame.add(jPanelTwo);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
Updated with "builder" example
This is a (very basic) example of a builder pattern, basically, you have a separate class which simply builds the UI and returns a JPanel (in this example)
More complex builders would allow you to add additional properties to adjust the outcome.
class CalculatorWhichUsesAInterface {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.setTitle("Calculator");
frame.add(CalculatorBuilder.build());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
public static class CalculatorBuilder {
public static JPanel build() {
JPanel jPanelOne = new JPanel();
jPanelOne.setLayout(new GridLayout(1, 1));
jPanelOne.add(new JButton("x"));
JPanel jPanelTwo = new JPanel(new BorderLayout());
JTextField field = new JTextField();
field.setText("2141987.01235");
jPanelTwo.add(field, BorderLayout.NORTH);
jPanelTwo.add(jPanelOne, BorderLayout.CENTER);
return jPanelTwo;
}
}
}
to not extend JFrame you have the right idea, but on your code above you'd need to first remove the extends JFrame but the way you declare your frame is fine:
JFrame frame = new JFrame("Title");
Then from there you just have to reference the object of it from then on, so for example:
frame.add(jPanelTwo,BorderLayout.CENTER)
Looks like everything you do in main (setTitle, setSize etc) you do for JFrame object that "comes" from inheritance (extends JFrame). So actually you are doing nothing with:
JFrame frame = new JFrame();
If you want not to use inheritance, you should invoke methods of JFrame object, not the CalculatorWhichUsesAInterface(). So the constructor should look like this (in main leave only creating the object):
class CalculatorWhichUsesAInterface{
JFrame frame = new JFrame();
public CalculatorWhichUsesAInterface(){
JPanel jPanelOne = new JPanel();
jPanelOne.setLayout(new GridLayout(1, 1);
jPanelOne.add(new JButton("x"));
JPanel jPanelTwo = new JPanel(new BorderLayout());
JTextField field = new JTextField();
field.setText("2141987.01235");
jPanelTwo.add(field, BorderLayout.NORTH);
jPanelTwo.add(jPanelOne, BorderLayout.CENTER);
frame.add(jPanelTwo, BorderLayout.CENTER); //DIFFERENCE
frame.setTitle("Calculator");
frame.setSize(500, 200);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
As you can see, I copied almost everyting from main to constructor, but it is invoked on different object (JFrame actually, not the CalculatorWhichUsesAInterface). But doing JFrame through inheritance is common way.

Adding buttons below JTextArea

I am trying to add two buttons below the JTextArea using the Eclipse WindowBuilder, but I can't. I tried to change the layout, but I couldn't find a way to add buttons where I want and to re-size the JTextArea in an easy way.
public TestScrollPane03() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JTextArea textArea = new JTextArea(100, 50);
JScrollPane scrollPane = new JScrollPane(textArea);
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(scrollPane);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
How would I go about adding buttons below my original textArea?
You need to have two panels, one for your textArea, and one for your input (in this case buttons). I think something like this is what you are looking for:
public class Test
{
public static void createFrame()
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setOpaque(true);
JTextArea textArea = new JTextArea(15, 50);
textArea.setWrapStyleWord(true);
textArea.setEditable(false);
textArea.setFont(Font.getFont(Font.SANS_SERIF));
JScrollPane scroller = new JScrollPane(textArea);
scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
JPanel inputpanel = new JPanel();
inputpanel.setLayout(new FlowLayout());
JTextField input = new JTextField(20);
JButton button = new JButton("Enter");
DefaultCaret caret = (DefaultCaret) textArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
panel.add(scroller);
inputpanel.add(input);
inputpanel.add(button);
panel.add(inputpanel);
frame.getContentPane().add(BorderLayout.CENTER, panel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
frame.setResizable(false);
input.requestFocus();
}
});
}
public static void main(String... args)
{
createFrame();
}
}
If you want your frame to look more like those of the OS you are running on, you can add .setLookAndFeel() before you make the frame visible:
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
What adding the UIManager looks like (notably a bit smaller):

Categories