JScrollPane не отображается, элементы переполняются

Сейчас работаю над заданием, и я, по сути, пишу свой первый графический интерфейс. Все работает нормально, кроме моей полосы прокрутки - после ее добавления она не только не будет отображаться, но даже после того, как я закомментировал ее, ПОСЛЕДНИЙ добавленный элемент (через вызов функции .add) покрывает ВЕСЬ графический интерфейс. Установка макета на null, похоже, исправила это, но я не уверен, поможет ли это или помешает первой проблеме. Я уже просмотрел документацию и примеры Oracle и не понял, что мне нужно. Вот соответствующий код (переменные a-g, которые кажутся плавающими в пространстве, являются частью отдельного раздела, и я не вставлял его, чтобы изолировать код графического интерфейса):

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    public class Example
        {
        public static void main(String[] args) 
        {       

    JFrame mygui = new JFrame();
    mygui.getContentPane();
    mygui.setBounds(100, 100, 700, 500);
    mygui.setLayout(new BorderLayout()); //playing with layout here

    JLabel first = new JLabel("integer:");
    JLabel second = new JLabel("float:");
    JLabel third = new JLabel("short:");
    JLabel fourth = new JLabel("long:");
    JLabel fifth = new JLabel("byte:");
    JLabel sixth = new JLabel("double:");
    JLabel seventh = new JLabel("boolean:");
    JTextField myint = new JTextField("" + a);
    JTextField myfloat = new JTextField("" + b);
    JTextField myshort = new JTextField("" + c);
    JTextField mylong = new JTextField("" + d);
    JTextField mybyte = new JTextField("" + e);
    JTextField mydbl = new JTextField("" + f);
    JTextField mybool = new JTextField("" + g);
    JTextArea myarea = new JTextArea();
    JScrollPane scrolla = new JScrollPane(myarea);  

    first.setOpaque(true);
    first.setBounds(20, 20, 50, 20);
    second.setOpaque(true);
    second.setBounds(20, 70, 50, 20);
    third.setOpaque(true);
    third.setBounds(20, 120, 50, 20);
    fourth.setOpaque(true);
    fourth.setBounds(20, 170, 50, 20);
    fifth.setOpaque(true);
    fifth.setBounds(20, 220, 50, 20);
    sixth.setOpaque(true);
    sixth.setBounds(20, 270, 50, 20);
    seventh.setOpaque(true);
    seventh.setBounds(20, 320, 50, 20);

    myint.setBounds(70, 20, 50, 20);
    myint.setOpaque(true);
    myfloat.setBounds(70, 70, 50, 20);
    myfloat.setOpaque(true);
    myshort.setBounds(70, 120, 50, 20);
    myshort.setOpaque(true);
    mylong.setBounds(70, 170, 80, 20);
    mylong.setOpaque(true);
    mybyte.setBounds(70, 220, 50, 20);
    mybyte.setOpaque(true);
    mydbl.setBounds(70, 270, 50, 20);
    mydbl.setOpaque(true);
    mybool.setBounds(70, 320, 50, 20);
    mybool.setOpaque(true);

    myarea.setBounds(200, 50, 250, 200);
    myarea.setOpaque(true);
    scrolla.setPreferredSize(new Dimension(250, 200));

    mygui.add(first);
    mygui.add(second);
    mygui.add(third);
    mygui.add(fourth);
    mygui.add(fifth);
    mygui.add(sixth);
    mygui.add(seventh);

    mygui.add(myint);
    mygui.add(myfloat);
    mygui.add(myshort);
    mygui.add(mylong);
    mygui.add(mybyte);
    mygui.add(mydbl);
    mygui.add(mybool);
    mygui.add(scrolla);

    myarea.append("" + errcheck + "\n");
    myarea.append("" + valcheck + "\n");

    while(y < 2)
    {
    myarea.append("" + a + "\n");
    myarea.append("" + b + "\n");
    myarea.append("" + c + "\n");
    myarea.append("" + d + "\n");
    myarea.append("" + e + "\n");
    myarea.append("" + f + "\n");
    myarea.append("" + g + "\n");
    myarea.append("" + w + "\n");
    myarea.append("" + u + "\n");
    myarea.append("" + v + "\n");
    myarea.append("" + secondary + "\n");
    myarea.append("" + whilecount + "\n");;
    y++;
    a--;
    }

    mygui.setVisible(true);
    mygui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
 }

Я уверен, что это что-то простое, но приветствуются любые отзывы.


person Antidiscrete    schedule 07.03.2013    source источник


Ответы (3)


BorderLayout имеет пять определенных мест, в которые можно добавлять компоненты ...

введите описание изображения здесь

Расположение по умолчанию - CENTER.

В основном, что происходит, когда вы добавляете каждый компонент в панель фрейма / содержимого, он удаляет последний и помещает его в середину, так как только один компонент может существовать в заданном месте.

Начните с изменения менеджера компоновки. Чтобы узнать, идеи

person MadProgrammer    schedule 07.03.2013

При использовании BorderLayout метод setBounds () не дает никакого эффекта. Используя BorderLayout,
вы можете исправить свои компоненты только в пяти позициях Север, Юг, Восток, Запад и Центр
Если вы не укажете позицию, подобную add(comp, BorderLayout.EAST), ваши компоненты будут отображаться
случайно. Добавление дополнительных компонентов без указания позиции приведет к наложению друг на друга и не даст четкого обзора.

Вы используете более пяти компонентов и не указываете позиции, поэтому область прокрутки
не появится.

Используйте GridBagLayout, чтобы получить правильный результат. Обратитесь к http://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html

person Mohan Raj B    schedule 07.03.2013

Удалите эту строку:

mygui.getContentPane();

потому что это не вещь. Также измените

mygui.setLayout(new BorderLayout()); //playing with layout here

to

mygui.getContentPane ().setLayout (null); // playing with layout here

потому что вы хотите самостоятельно указать границы для всех компонентов. Также измените

myarea.setBounds(200, 50, 250, 200);

to

scrolla.setBounds(200, 50, 250, 200);

и удалите следующую строку:

scrolla.setPreferredSize(new Dimension(250, 200));

потому что без менеджера компоновки вам не нужен предпочтительный размер. Также измените

mygui.add(first);
mygui.add(second);
mygui.add(third);
mygui.add(fourth);
mygui.add(fifth);
mygui.add(sixth);
mygui.add(seventh);

mygui.add(myint);
mygui.add(myfloat);
mygui.add(myshort);
mygui.add(mylong);
mygui.add(mybyte);
mygui.add(mydbl);
mygui.add(mybool);
mygui.add(scrolla);

to

mygui.getContentPane ().add(first);
mygui.getContentPane ().add(second);
mygui.getContentPane ().add(third);
mygui.getContentPane ().add(fourth);
mygui.getContentPane ().add(fifth);
mygui.getContentPane ().add(sixth);
mygui.getContentPane ().add(seventh);

mygui.getContentPane ().add(myint);
mygui.getContentPane ().add(myfloat);
mygui.getContentPane ().add(myshort);
mygui.getContentPane ().add(mylong);
mygui.getContentPane ().add(mybyte);
mygui.getContentPane ().add(mydbl);
mygui.getContentPane ().add(mybool);
mygui.getContentPane ().add(scrolla);

Потому что компоненты не должны добавляться непосредственно в JFrame, а только на его панель содержимого. После этих изменений все должно работать нормально. Вы увидите полосы прокрутки, когда в текстовой области будет достаточно текста. Вот исправленная версия вашего кода, которая работает у меня:

import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class Example
{
    public static void main (String [] args)
    {

        JFrame mygui = new JFrame ();
        mygui.getContentPane ();
        mygui.setBounds (100, 100, 700, 500);
        mygui.getContentPane ().setLayout (null); // playing with layout here

        JLabel first = new JLabel ("integer:");
        JLabel second = new JLabel ("float:");
        JLabel third = new JLabel ("short:");
        JLabel fourth = new JLabel ("long:");
        JLabel fifth = new JLabel ("byte:");
        JLabel sixth = new JLabel ("double:");
        JLabel seventh = new JLabel ("boolean:");
        JTextField myint = new JTextField ("a");
        JTextField myfloat = new JTextField ("b");
        JTextField myshort = new JTextField ("c");
        JTextField mylong = new JTextField ("d");
        JTextField mybyte = new JTextField ("e");
        JTextField mydbl = new JTextField ("f");
        JTextField mybool = new JTextField ("g");
        JTextArea myarea = new JTextArea ();
        JScrollPane scrolla = new JScrollPane (myarea);

        first.setOpaque (true);
        first.setBounds (20, 20, 50, 20);
        second.setOpaque (true);
        second.setBounds (20, 70, 50, 20);
        third.setOpaque (true);
        third.setBounds (20, 120, 50, 20);
        fourth.setOpaque (true);
        fourth.setBounds (20, 170, 50, 20);
        fifth.setOpaque (true);
        fifth.setBounds (20, 220, 50, 20);
        sixth.setOpaque (true);
        sixth.setBounds (20, 270, 50, 20);
        seventh.setOpaque (true);
        seventh.setBounds (20, 320, 50, 20);

        myint.setBounds (70, 20, 50, 20);
        myint.setOpaque (true);
        myfloat.setBounds (70, 70, 50, 20);
        myfloat.setOpaque (true);
        myshort.setBounds (70, 120, 50, 20);
        myshort.setOpaque (true);
        mylong.setBounds (70, 170, 80, 20);
        mylong.setOpaque (true);
        mybyte.setBounds (70, 220, 50, 20);
        mybyte.setOpaque (true);
        mydbl.setBounds (70, 270, 50, 20);
        mydbl.setOpaque (true);
        mybool.setBounds (70, 320, 50, 20);
        mybool.setOpaque (true);

        myarea.setOpaque (true);
        myarea.setBackground (Color.yellow);
        scrolla.setBounds (200, 50, 250, 200);
        scrolla.setPreferredSize (new Dimension (250, 200));

        mygui.getContentPane ().add (first);
        mygui.getContentPane ().add (second);
        mygui.getContentPane ().add (third);
        mygui.getContentPane ().add (fourth);
        mygui.getContentPane ().add (fifth);
        mygui.getContentPane ().add (sixth);
        mygui.getContentPane ().add (seventh);

        mygui.getContentPane ().add (myint);
        mygui.getContentPane ().add (myfloat);
        mygui.getContentPane ().add (myshort);
        mygui.getContentPane ().add (mylong);
        mygui.getContentPane ().add (mybyte);
        mygui.getContentPane ().add (mydbl);
        mygui.getContentPane ().add (mybool);
        mygui.getContentPane ().add (scrolla);

        myarea.append ("sdfgsdfgsdfgsf\n");

        mygui.setVisible (true);
        mygui.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
    }
}
person Mikhail Vladimirov    schedule 07.03.2013
comment
Пожалуйста, никогда не предлагайте новичку использовать null макет, у них есть достаточно, чтобы справиться, не имея с этим заниматься. Это плохая практика, и в этой ситуации нет никакой пользы, кроме как еще больше запутать их. - person MadProgrammer; 07.03.2013
comment
-1, когда вы добавляете компонент во фрейм, он добавляет компонент в панель содержимого за вас, поэтому использование getContentPane () не требуется и не исправит / не изменит проблему. Кроме того, использование пустого макета - плохая идея, и его не следует использовать для создания такой формы. Лучший способ сделать это - создать JPanel с соответствующим LayoutManager (ами) и добавить панель во фрейм. - person camickr; 07.03.2013
comment
@MadProgrammer В чем проблема с нулевым макетом? Менеджеры компоновки - довольно сложная область, и явное указание границ для всех компонентов может быть хорошим способом для новичка упростить работу. - person Mikhail Vladimirov; 07.03.2013
comment
Менеджеры компоновки могут быть сложными, но их функциональность значительно сокращает проблемы, связанные с различиями в различных платформах. Вы не можете контролировать потенциальный размер шрифта в настройках DPI в разных системах, работающих под управлением одной и той же ОС, не говоря уже о размерах разных ОС. Пренебрежение менеджерами компоновки означает пренебрежение одним из самых мощных элементов API, которые может предложить Swing. Он хотел бы сказать некоторым, чтобы они написали там все приложение на main. Конечно, это легко, но это не так - person MadProgrammer; 07.03.2013
comment
Менеджер компоновки делает больше, чем просто позиционирует компоненты. Они также вычисляют предпочтительный размер панели, чтобы прокрутка работала правильно. - person camickr; 07.03.2013