JScrollPane behaves unnormally with JTextArea - java

I asked a question before, on how to make a JTextField insert its text from beneath. Now I got some problem with the code. I edited a little bit, just for testing. Here is the code I'm using right now:
public class BaseTextAreaDemo {
private static JTextArea textArea;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
final JFrame frame = new JFrame("Base JTextArea App");
final JPanel panel = new JPanel();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
panel.setLayout(new BorderLayout());
JPanel textAreaPanel = getBaseTextArea();
JScrollPane scrollPane = new JScrollPane(textAreaPanel) {
public Dimension getPreferredSize() {
return new Dimension(300, 230);
}
};
panel.add(scrollPane, BorderLayout.SOUTH);
JTextField textField = new JTextField();
textField.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
textArea.append(arg0.getActionCommand() + "\n");
}
});
frame.add(panel, BorderLayout.CENTER);
frame.add(textField, BorderLayout.SOUTH);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel getBaseTextArea() {
textArea = new JTextArea();
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
textArea.append("bla bla bla\n");
textArea.append("new text here");
JPanel panel = new JPanel(new BorderLayout());
panel.setBackground(textArea.getBackground());
panel.setBorder(textArea.getBorder());
textArea.setBorder(null);
panel.add(textArea, BorderLayout.SOUTH);
return panel;
}
});
}
I just added a textField, because I also need one in the program I need this in, and it's useful to add more lines this way.
Now the problem is, when I run this program and I add lines until a vertical scrollbar appears, a horizontal comes out too. I already figured that you can just turn that off, but then some text falls out of the screen. Also, when you make the frame wider, and than return it to it's normal size, the horizontal scrollbar stays at the size from the widened window.
Another problem is that the speed of scrolling is very low in the JTextField.

Try to set the PreferedSize of the textArea to the same as ur JScrollPane:
textArea.setPreferedSize(Dimension(300, 230));
You can aswell just disable Horizontal Scrollbar:
scrollPane.setHorizonalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
You can set the Scrollspeed like this:
scrollPane.getVerticalScrollBar().setUnitIncrement(16);
i could solved the problem: its the panel u are adding to the scrollpane. Add the JTextArea directly to the ScrollPane and the Horizonal Bar only appear if needed:
textArea = new JTextArea();
JScrollPane scrollPane = new JScrollPane(textArea);

if you want to fully remove the horizontal scrollbar then I suggest you invoke this line of code on your JScrollPane:
scrollPane.setHorizonalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

Related

How to create multiple frames or windows in GUI?

I am new to creating GUI. I want to know how to create multiple windows. I want to show another frame if a button is to be clicked. I have searched how and i saw that some people are making another GUI form and just calling the other form i a button was clicked, but i dont understand how.
There are numerous ways to do this. One of the main ways is to create a new Java Class with its own properties. Here is a nexample:
JButton button = new JButton("Button_Leads_To_This_Window");
button.addActionListener( new ActionActionListener()
{
public void actionPerformed(ActionEvent e)
{
NewFrame();
}
});
This will allow the button to call a new window, similar as the way you called the "My Empire" window. For example NewFrame() class will look like this:
public static void newFrame()
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
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();
}
});
}
Here is more information to the matter:
https://www.thoughtco.com/create-a-simple-window-using-jframe-2034069
https://www.youtube.com/watch?v=RMz9LYY2g4A
Good luck.

using both JTabbedPane and JScrollPane

As you see the code, I would like to implement the 2nd tab with a text area, scrolling, and a button down there. This (JScrollPane scr = new JScrollPane(secondTab(panel2));) code was in the function, private static JTextArea secondTab(JPanel panel) before but I took it out of the function and put that back to MainFrame. Because the scroll and text area didn't show up. Now that I moved the code to mainframe the tex tarea and scroll are visible, but I'm struggling with making the button showing up in the 2nd tab. Do you guys have any idea?
public MainFrame(String username)
{
JTabbedPane tab = new JTabbedPane();
mainFrame.add(tab, BorderLayout.CENTER);
JPanel panel1 = new JPanel();
firstTab(panel1);
tab.add("babababa", panel1);
JPanel panel2 = new JPanel();
JScrollPane scr = new JScrollPane(secondTab(panel2));
JButton saveButton = new JButton("Save");
panel2.add(saveButton);
saveButton.setBounds(190, 280, 80, 40);
tab.add("hahaha", panel2.add(scr));
mainFrame.setBounds(200,200,500,400);
mainFrame.setVisible(true);
}
private static JTextArea secondTab(JPanel panel) {
panel.setLayout(null);
final JTextArea nameTextArea=new JTextArea();
nameTextArea.setBounds(10,10,440,270);
nameTextArea.setLineWrap(true);
return nameTextArea;
}
}
You should avoid use of null layout as this makes for very inflexible GUI's that while they might look good on one platform look terrible on most other platforms or screen resolutions and that are very difficult to update and maintain. Not only that, JScrollPanes do not work well when the viewport view (the component that you display inside of the JScrollPane) uses null layout. Not only that, if you set the bounds or even the preferred size of a JTextArea, it will not expand inside the JScrollPane and you won't see scrollbars.
Solution:
Avoid using null layouts like the plague.
Learn and use the layout managers: The Swing Layout Manager Tutorials
Never set a JTextArea's size or preferredSize. Instead consider setting its columns and rows.
For example:
import java.awt.BorderLayout;
import javax.swing.*;
public class MainFrame2 extends JPanel {
private JTabbedPane tabbedPane = new JTabbedPane();
private JTextArea textArea = new JTextArea(20, 40);
public MainFrame2() {
tabbedPane.add("Bahahahaha", new JPanel());
tabbedPane.add("TextArea Info", createTextAreaPane());
setLayout(new BorderLayout());
add(tabbedPane, BorderLayout.CENTER);
}
private JComponent createTextAreaPane() {
JPanel btnPanel = new JPanel();
btnPanel.add(new JButton("Save"));
JPanel textAreaPane = new JPanel(new BorderLayout());
textAreaPane.add(new JScrollPane(textArea), BorderLayout.CENTER);
textAreaPane.add(btnPanel, BorderLayout.SOUTH);
return textAreaPane;
}
private static void createAndShowGui() {
MainFrame2 mainPanel = new MainFrame2();
JFrame frame = new JFrame("Main Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_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();
}
});
}
}
It's better to build each tab panel in each method.
private JPanel buildFirstTab() {
// create new panel
// add components to the panel
// return the panel
}
private JPanel buildSecondTab() {
// create new panel
// create JScrollPane
// create JTextArea
// add text area to scrollpane by calling scrollpane.setViewPort method
// add scrollpane to the panel
// create button
// add button to the panel
// return the panel
}
public MainFrame(String username) {
JTabbedPane tab = new JTabbedPane();
mainFrame.add(tab, BorderLayout.CENTER);
tab.add("1st tab", buildFirstTab());
tab.add("2nd tab", buildSecondTab());
mainFrame.setBounds(200,200,500,400);
mainFrame.setVisible(true);
}
Adding to the previous answer, try to use the simple layout like BoxLayout (adds components on top of each other), or FlowLayout (adds components next to previous component), then learn more complex layout like GridBagLayout (so far, this is the best layout for me, most of the time).

location and size of jtextarea in jscrollpane is not set

I am working on the editor. I am using Java swing for it. I have embedded a JTextArea with JScrollPane. i want to position the jtextarea of particular size at the middle of JScrollPane. To do this I used setLocation function. But this is not working?
public class ScrollPaneTest extends JFrame {
private Container myCP;
private JTextArea resultsTA;
private JScrollPane scrollPane;
private JPanel jpanel;
public ScrollPaneTest() {
resultsTA = new JTextArea(50,50);
resultsTA.setLocation(100,100);
jpanel=new JPanel(new BorderLayout());
jpanel.add(resultsTA,BorderLayout.CENTER);
scrollPane = new JScrollPane(jpanel,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setPreferredSize(new Dimension(800, 800));
scrollPane.setBounds(0, 0, 800, 800);
setSize(800, 800);
setLocation(0, 0);
myCP = this.getContentPane();
myCP.setLayout(new BorderLayout());
myCP.add(scrollPane);
setVisible(true);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public static void main(String[] args) {
new ScrollPaneTest();
}
}
You simply have to add the JTextArea to the JScrollPane, and add it to the CENTER of the JPanel having BorderLayout.
Don't use AbsolutePositioning. Add a proper LayoutManager, and let LayoutManager do the rest for positioning and sizing your components on the screen.
In order to use the setBounds(...) method you have to use a null Layout for your component, which is not worth using, provided the perspective, as mentioned in the first paragraph of the AbsolutePositioning. Though in the code example provided by you, you are doing both the thingies together i.e. using Layout and using AbsolutePositioning, which is wrong in every way. My advice STOP DOING IT :-)
In the example provided the ROWS and COLUMNS provided by you are sufficient to size the JTextArea by the Layout concern.
Code Example :
import java.awt.*;
import javax.swing.*;
public class Example
{
private JTextArea tarea;
private void displayGUI()
{
JFrame frame = new JFrame("JScrollPane Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout(5, 5));
JScrollPane textScroller = new JScrollPane();
tarea = new JTextArea(30, 30);
textScroller.setViewportView(tarea);
contentPane.add(textScroller);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
new Example().displayGUI();
}
});
}
}

More than one JPanel in a Frame / having a brackground Image and another Layer with Components on the top

I've got a JFrame with a JPanel in which there is a JLabel with an ImageIcon(). Everything's working perfectly, problem is i now want to add another JPanel with all the other stuff like buttons and so on to the JFrame. But it still shows the background Image on top and nothing with the second JPanel.
Can someone help me?
Here is an extract of my code:
JFrame window = new JFrame("Http Download");
/*
* Background Section
*/
JPanel panel1 = new JPanel();
JLabel lbl1 = new JLabel();
/*
* Component Section
*/
JPanel panel2 = new JPanel();
JLabel lbl2 = new JLabel();
/*
* Dimension Section
*/
Dimension windowSize = new Dimension(800, 600);
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
public HTTPDownloadGUI() {
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel1.setLayout(null);
panel1.setSize(windowSize);
panel1.setOpaque(false);
panel2.setLayout(null);
panel2.setSize(windowSize);
panel2.setOpaque(false);
lbl1.setSize(windowSize);
lbl1.setLocation(0, 0);
lbl1.setIcon(new ImageIcon(getClass().getResource("bg1.png")));
panel1.add(lbl1);
lbl2.setBounds(0, 0, 100, 100);
//lbl2.setIcon(new ImageIcon(getClass().getResource("bg2.png")));
lbl2.setBackground(Color.GREEN);
panel2.add(lbl2);
panel1.add(panel2);
window.add(panel1);
int X = (screen.width / 2) - (windowSize.width / 2);
int Y = (screen.height / 2) - (windowSize.height / 2);
window.setBounds(X,Y , windowSize.width, windowSize.height);
window.setVisible(true);
}
Avoid null layouts, here more trouble then they are worth
Set the frame a layout to BorderLayout
Add the label to the frame
Set the labels layout to BorderLayout
Create you panel and set it's opaque property to false
Add the other components to as per normal
Add the panel to the label
Checkout
Are there any issues with placing image as background on an extended JFrame?
Place JLabel on top of JLabel with image in
For examples
Update with example
panel1 is the main background...
Set panel1's layout to BorderLayout
Add lbl1 to panel1
Set lbl1's layout to BorderLayout
Set panel2's layout to what ever you want to use...
Set panel2's opacity property to false (panel2.setOpacity(false))
Add lbl2 to panel2
Add panel2 to lbl1
Add panel1 to what every you want.
public class TestLayout17 {
public static void main(String[] args) {
new TestLayout17();
}
public TestLayout17() {
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 {
/*
* Background Section
*/
JPanel panel1 = new JPanel();
JLabel lbl1 = new JLabel();
/*
* Component Section
*/
JPanel panel2 = new JPanel();
JLabel lbl2 = new JLabel();
/*
* Dimension Section
*/
Dimension windowSize = new Dimension(800, 600);
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
public TestPane() {
setLayout(new BorderLayout());
panel1.setLayout(new BorderLayout());
lbl1.setLayout(new BorderLayout());
URL url = getClass().getResource("/bg1.gif");
System.out.println(url);
try {
BufferedImage image = ImageIO.read(url);
Image smaller = image.getScaledInstance(-1, image.getHeight() / 2, Image.SCALE_SMOOTH);
lbl1.setIcon(new ImageIcon(smaller));
} catch (Exception e) {
e.printStackTrace();
}
// lbl1.setIcon(new ImageIcon(url));
panel1.add(lbl1);
add(panel1);
panel2.setLayout(new GridBagLayout());
panel2.setOpaque(false);
lbl2.setBorder(new EmptyBorder(8, 8, 8, 8));
lbl2.setBackground(Color.GREEN);
lbl2.setText("Say hello");;
lbl2.setOpaque(true);
panel2.add(lbl2);
lbl1.add(panel2);
}
}
}
The reason that nothing appears to be shown for panel2 is because there is nothing to display. Simply setting text for lbl2 will show that the JPanel itself is visible:
JLabel lbl2 = new JLabel("Some text");
I would, however advise against using null layout as it places the overhead on the developer for setting locations & dimensions which a layout manager can easily manage for you.
I would advise you to heed MadProgrammer's advice. If you chose to go with a null layout, make sure you are removing the previous JPanel and adding the new one to the content pane window.setContentPane(panel2); and calling window.repaint().

Adding label and text box control to GUI

I would like to know what code to insert and where to add a simple label that can just say the word "Label" and a input text box that I can enter a number.
public CalculateDimensions() {
JTabbedPane Tab = new JTabbedPane();
JPanel jplInnerPanel1 = createInnerPanel("First Tab");
Tab.addTab("One", jplInnerPanel1);
Tab.setSelectedIndex(0);
JPanel jplInnerPanel2 = createInnerPanel("Second Tab");
Tab.addTab("Two", jplInnerPanel2);
JPanel jplInnerPanel3 = createInnerPanel("Third Tab");
Tab.addTab("Three", jplInnerPanel3);
JPanel jplInnerPanel4 = createInnerPanel("Fourth Tab");
Tab.addTab("Four", jplInnerPanel4);
JPanel jplInnerPanel5 = createInnerPanel("Fifth Tab");
Tab.addTab("Five", jplInnerPanel5);
setLayout(new GridLayout(1, 1));
add(Tab);
}
protected JPanel createInnerPanel(String text) {
JPanel jplPanel = new JPanel();
JLabel jlbDisplay = new JLabel(text);
jlbDisplay.setHorizontalAlignment(JLabel.CENTER);
jplPanel.setLayout(new GridLayout(1, 1));
jplPanel.add(jlbDisplay);
return jplPanel;
}
public static void main(String[] args) {
JFrame frame = new JFrame("Calculations");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.getContentPane().add(new CalculateDimensions(),
BorderLayout.CENTER);
frame.setSize(400, 400);
frame.setVisible(true);
}
}
The Swing tutorial is an excellent resource for building GUIs.
Take a look at the visual guide and click on the components you want for detailed how to guides for creating text boxes, and other items.
http://download.oracle.com/javase/tutorial/ui/features/components.html
in your public static void main() method you should not instantiate JFrame frame = new JFrame("Calculations");
This is where you are going wrong!
That line should read:
CalculateDimensions frame = new CalculateDimensions("Calculations");
You will also need to change the line says
public class CalculateDimensions {
(it's near the top) says
public class CalculateDimensions extends JFrame {
then inside the method called public class CalculateDimensions { you need to add a line after JPanel jplInnerPanel1 = createInnerPanel("First Tab"); which says
jplInnerPanel1.add(new JLabel("Label");

Categories

Resources