Макет Java Swing для прокручиваемой таблицы?

В настоящее время у меня есть JPanel внутри JPanel, где я хотел бы разместить свой JScrollPane/JTable. У меня возникли проблемы с размещением его там, где я хочу. Я хотел бы, чтобы таблица соответствовала всей ширине JPanel, но занимала столько места, сколько необходимо для вертикального отображения всех динамических данных в таблице.

Это код, который у меня сейчас есть, и на картинке он выглядит так. Синяя область — это вложенная панель для ситуации таблицы/прокрутки. А еще зачем дурацкая серая коробка под столом. Как мне избавиться от этого? Извините за фото, данные конфиденциальны. Спасибо.

    JPanel panel = new JPanel();
    panel.setBounds(50, 100, 300, 450);
    panel.setBackground(Color.blue);
    contentPane.add(panel); //contentPane is the outter panel

    JScrollPane scrollpane = new JScrollPane(table); //table was created earlier
    panel.add(scrollpane,BorderLayout.NORTH);

панель таблицы

Пример программы (мне не нужен этот большой прямоугольник под столом)

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;

public class Test {

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setBounds(350,100,1000,800);
    JPanel contentPane = new JPanel(new BorderLayout());
    frame.setContentPane(contentPane);
    JTable table = new JTable(5,5);
    JScrollPane scrollpane = new JScrollPane(table);
    table.setFillsViewportHeight(true);
    contentPane.add(scrollpane,BorderLayout.NORTH);
    frame.revalidate();
}

}

person zProgrammer    schedule 12.11.2013    source источник
comment
Я вижу setBounds, что заставляет меня думать, что вы используете нулевой макет...   -  person MadProgrammer    schedule 13.11.2013
comment
Я использую абсолютное позиционирование для внешней панели. Я не понимаю, почему это будет иметь значение.   -  person zProgrammer    schedule 13.11.2013
comment
@MadProgrammer, его код также не сообщает нам макет JPanel экземпляра panel, но он добавляет компонент с ограничением BorderLayout :)   -  person Sage    schedule 13.11.2013


Ответы (2)


И почему под столом дурацкая серая коробка? Как мне избавиться от этого?

Попробуйте использовать table.setFillsViewportHeight(true);< /strong> после добавления его в JSCrollPane: как вы делаете сейчас:

   JPanel panel = new JPanel();
   // other code
   panel.setLayout(new BorderLayout()); // not sure whither you are already doing this

   JScrollPane scrollPane = new JScrollPane(table);
   table.setFillsViewportHeight(true);

   panel.add(scrollPane, BorderLayout.CENTER);

вызов функции setFillsViewportHeight(true) устанавливает свойство fillsViewportHeight. Когда это свойство равно true, table использует всю высоту контейнера, даже если table не имеет достаточного количества строк для использования всего вертикального пространства.

Примечание.

  1. Я не вижу, чтобы вы добавили макет к panel, к которому вы добавили JScrollPane. Я надеюсь, вы знаете, что JPanel использует FlowLayout в качестве макета по умолчанию, который подчиняется подсказке предпочтительного размера компонента. Опять же, panel.add(scrollpane, BorderLayout.NORTH); вызывает двусмысленность. Поскольку мы используем ограничение: BorderLayout.NORTH для компонента, который имеет BorderLayout в качестве менеджера компоновки.

  2. Панель содержимого фрейма имеет BorderLayout в качестве диспетчера макетов по умолчанию. Вы устанавливаете привязку к panel с помощью setBounds(), что мы обычно делаем при работе с макетом AbsoluteLayout(null). И AbsoluteLayout никуда не годится при разработке приложений на Swing.

person Sage    schedule 12.11.2013
comment
JPanel по-прежнему использует FlowLayout, что означает, что панель прокрутки может не заполнять всю область... - person MadProgrammer; 13.11.2013
comment
@MadProgrammer, я заметил проблему. Это действительно двусмысленно: когда он делает, panel.add(scrollpane, BorderLayout.NORTH); - person Sage; 13.11.2013
comment
Я бы не хотел, чтобы таблица заполняла весь контейнер. Я просто хочу, чтобы он был настолько большим, насколько это необходимо для просмотра всех данных, и если он больше, чем контейнер, он должен заполнить все это полосой прокрутки. - person zProgrammer; 13.11.2013
comment
@Robert, Get some people skills and grow up - Думаю, тебе нужны навыки работы с людьми. Вы тот, кто просит о помощи, а затем комментирует, когда люди пытаются помочь. Невероятно сложно дать вам точный совет из-за такого плохого вопроса. Код, который вы разместили, в основном бесполезен. Заявление о том, что это не работает, не дает нам никакой информации. Опубликуйте свои SSCCE шоу, которые вы пробовали, основываясь на всех полученных вами предложениях. - person camickr; 13.11.2013
comment
@camickr, модератор удалил комментарии, как кажется. Я отметил его комментарии. Будем надеяться, что он опубликует SSCCE, чтобы сообщить нам, что именно он пытается сделать. - person Sage; 13.11.2013
comment
Извините, ребята, я постараюсь сделать один. - person zProgrammer; 13.11.2013
comment
Я добавил короткую программу. Метод, который вы заставили меня вызвать, только изменяет большой прямоугольник под столом с серого на белый. - person zProgrammer; 13.11.2013

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

Что, если у вас есть 100 строк, они не смогут одновременно отображаться во фрейме?

Переопределите метод getPreferredScrollableViewportSize() JTable, чтобы он возвращал разумное число, это число должно включать высоту JTableHeader. Таким образом, вы, вероятно, захотите ограничить высоту разумным количеством строк + заголовок таблицы.

panel.add(scrollpane,BorderLayout.NORTH);

Ограничение СЕВЕР ничего не делает. JPanel по умолчанию использует FlowLayout. Вам нужно будет установить макет панели на BorderLayout.

Редактировать:

Вас попросили показать свой SSCCE, который включает предложение, сделанное в этих ответах. Вы не:

  1. реализован метод getPreferredScrollableViewportSize()
  2. сделал пакет() на фрейме после того, как вы добавили все компоненты в фрейм.

Другие общие комментарии.

  1. Не указывайте размер рамки. Для этого и предназначен метод pack(). Даже если бы вы сделали, вы бы не стали жестко кодировать размер. Мой монитор даже не настолько велик, чтобы отобразить кадр указанного вами размера.

  2. Не делайте рамку видимой, пока не добавите в нее все компоненты.

  3. Графический интерфейс должен быть создан в потоке отправки событий.

person camickr    schedule 12.11.2013
comment
Если есть 100 строк, то он должен заполнить все пространство по вертикали прокруткой (отсюда и точка панели прокрутки). - person zProgrammer; 13.11.2013
comment
Менеджеры компоновки работают не так. Компонент предлагает подсказки для менеджера компоновки. Таким образом, панель не может сказать, что мне нужно 500 пикселей по высоте, потому что в кадре может быть другая панель, которой также нужно 500 пикселей по высоте, что было бы слишком много для кадра. Таким образом, каждый компонент должен иметь предпочтительный размер. Затем вы упаковываете кадр и используете менеджеры компоновки, которые позволяют компоненту увеличиваться/уменьшаться, а размер кадра изменяется, что означает, что вы НЕ должны добавлять свой компонент на СЕВЕР, потому что он никогда не изменит высоту, даже если доступно больше места. - person camickr; 13.11.2013
comment
Итак, какой макет вы рекомендуете для управления этим? Я просто не уверен, как вы можете изменить размер на панели. - person zProgrammer; 13.11.2013
comment
Вам дали ответ на это неделю назад в одном из ваших других вопросов. Вы не только не последовали этому совету, но еще и не разместили SSCCE!!! - person camickr; 13.11.2013
comment
Я добавил короткую программу. Пока он работает, я бы хотел, чтобы этого большого прямоугольника под столом не было. Я хочу, чтобы в таблице отображались только ячейки. И в этом примере я устанавливаю количество столбцов и строк, но в моей реальной программе строки, в частности, изменяются в зависимости от критериев, поэтому она должна иметь возможность динамически изменять размер. - person zProgrammer; 13.11.2013
comment
Я до сих пор не знаю, почему я установил для него предпочтительный размер. Никогда не должно быть установленного размера для таблицы. Он просто не должен превышать площадь панели. Я не понимаю, почему ограничение размера таблицы может что-то сделать. Мне не нужен заданный размер таблицы. Кроме того, метод pack() ни разу не упоминался в этой ветке, поэтому, хотя я ценю это предложение, не делайте вид, что я не знал о нем. Пожалуйста, прочитайте мой вопрос и дайте полезную информацию вместо того, чтобы жаловаться на то, что я не делаю то, что не имеет отношения к тому, чего я хочу. - person zProgrammer; 15.11.2013
comment
@ Роберт Also the method pack() was not mentioned once in this thread - серьезно. Вы действительно должны читать, прежде чем комментировать. Please read my question - Теперь твоя очередь читать мой ответ. - person camickr; 15.11.2013
comment
@ Роберт Also the method pack() was not mentioned once in this thread - seriously. Вы действительно должны читать, прежде чем комментировать. Please read my question - Теперь твоя очередь читать мой ответ. Я сделал честное усилие, чтобы понять ваше требование, и сделал то, что я считаю уместным предложением. Вы должны приложить усилия для реализации моего предложения, потому что код, который вы разместили, не показывает никаких усилий, поэтому я не уверен, как еще помочь. - person camickr; 15.11.2013