JScrollPane没有出现

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JScrollPane没有出现相关的知识,希望对你有一定的参考价值。

我已经查看了许多类似于此的其他线程,但没有一个修复工作。添加之后我尝试过做contentPanel.revalidate();contentPanel.repaint();。我已经尝试将JScrollPane和JTextArea添加到contentPanel,我已经单独尝试过。我尝试过从JTextArea到JTextPane,但是没有一个工作。没有JScrollPane,JTextArea显示正常,但是当我添加它时,JTextArea完全消失了。我正在使用null布局,我认为这可能是问题,但如果有一个解决方案不涉及更改布局,我宁愿这样做。如果没有其他方法可以修改布局,请告诉我。谢谢。

下面是代码(它是一个JDialog窗口,它是主窗口的弹出窗口)`:

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.text.SimpleDateFormat;
import java.time.DateTimeException;
import java.time.LocalDateTime;
import java.time.Month;
import java.util.ArrayList;
import java.util.Calendar;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;

public class TransactionsDialog extends JDialog
{
    private static final long serialVersionUID = 6939141004692809959L;
    private final JPanel contentPanel = new JPanel();
    private SimpleDateFormat monthDate = new SimpleDateFormat("MMMM");
    private JTextArea txtTransactions;
    private JComboBox<String> comboStartMonth;
    private JComboBox<Integer> comboStartDay;
    private JComboBox<Integer> comboStartYear;
    private JComboBox<String> comboEndMonth;
    private JComboBox<Integer> comboEndDay;
    private JComboBox<Integer> comboEndYear;
    private JCheckBox chckbxStartDate;
    private JCheckBox chckbxEndDate;

    /**
     * Create the dialog.
     */
    public TransactionsDialog(BankAccount account)
    {
        setResizable(false);
        /**
         * Populating (Day, Month, Year) Arrays.
         */
        ArrayList<String> monthList = new ArrayList<String>();
        for(int month = 0; month < 12; month++)
        {
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.MONTH, month);
            String monthName = monthDate.format(calendar.getTime());

            monthList.add(monthName);
        }

        ArrayList<Integer> dayList = new ArrayList<Integer>();
        for(int day = 1; day <= 31; day++)
        {
            dayList.add(day);
        }

        ArrayList<Integer> yearList = new ArrayList<Integer>();
        for(int year = 1980; year <= Calendar.getInstance().get(Calendar.YEAR); year++)
        {
            yearList.add(year);
        }

        setTitle("Transactions of " + account);
        setBounds(100, 100, 404, 300);
        getContentPane().setLayout(new BorderLayout());
        contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
        getContentPane().add(contentPanel, BorderLayout.CENTER);
        contentPanel.setLayout(null);

        comboStartMonth = new JComboBox<String>();
        comboStartMonth.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                listTransactions(account);
            }
        });
        comboStartMonth.setModel(new DefaultComboBoxModel<String>(monthList.toArray(new String[monthList.size()])));
        comboStartMonth.setEnabled(false);
        comboStartMonth.setBounds(100, 8, 118, 20);
        contentPanel.add(comboStartMonth);

        comboStartDay = new JComboBox<Integer>();
        comboStartDay.setModel(new DefaultComboBoxModel<Integer>(dayList.toArray(new Integer[dayList.size()])));
        comboStartDay.setEnabled(false);
        comboStartDay.setBounds(228, 8, 71, 20);
        comboStartDay.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                listTransactions(account);
            }
        });
        contentPanel.add(comboStartDay);

        comboStartYear = new JComboBox<Integer>();
        comboStartYear.setModel(new DefaultComboBoxModel<Integer>(yearList.toArray(new Integer[yearList.size()])));
        comboStartYear.setSelectedIndex(comboStartYear.getItemCount() - 1);
        comboStartYear.setEnabled(false);
        comboStartYear.setBounds(309, 8, 71, 20);
        comboStartYear.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                listTransactions(account);
            }
        });
        contentPanel.add(comboStartYear);

        comboEndMonth = new JComboBox<String>();
        comboEndMonth.setModel(new DefaultComboBoxModel<String>(monthList.toArray(new String[monthList.size()])));
        comboEndMonth.setEnabled(false);
        comboEndMonth.setBounds(100, 34, 119, 20);
        comboEndMonth.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                listTransactions(account);
            }
        });
        contentPanel.add(comboEndMonth);

        comboEndDay = new JComboBox<Integer>();
        comboEndDay.setModel(new DefaultComboBoxModel<Integer>(dayList.toArray(new Integer[dayList.size()])));
        comboEndDay.setEnabled(false);
        comboEndDay.setBounds(228, 34, 71, 20);
        comboEndDay.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                listTransactions(account);
            }
        });
        contentPanel.add(comboEndDay);

        comboEndYear = new JComboBox<Integer>();
        comboEndYear.setModel(new DefaultComboBoxModel<Integer>(yearList.toArray(new Integer[yearList.size()])));
        comboEndYear.setSelectedIndex(comboEndYear.getItemCount() - 1);
        comboEndYear.setEnabled(false);
        comboEndYear.setBounds(309, 34, 71, 20);
        comboEndYear.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                listTransactions(account);
            }
        });
        contentPanel.add(comboEndYear);

        txtTransactions = new JTextArea();
        txtTransactions.setFont(new Font("Courier New", Font.PLAIN, 11));
        txtTransactions.setEditable(false);
        txtTransactions.setBounds(10, 63, 368, 187);

        JScrollPane txtTScrollPane = new JScrollPane(txtTransactions);
        contentPanel.add(txtTScrollPane);
        contentPanel.revalidate();
        contentPanel.repaint();

        chckbxStartDate = new JCheckBox("Start Date:");
        chckbxStartDate.setBounds(6, 7, 89, 23);
        chckbxStartDate.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                if(chckbxStartDate.isSelected())
                {
                    comboStartMonth.setEnabled(true);
                    comboStartDay.setEnabled(true);
                    comboStartYear.setEnabled(true);            
                }
                else
                {
                    comboStartMonth.setEnabled(false);
                    comboStartDay.setEnabled(false);
                    comboStartYear.setEnabled(false);
                }

                listTransactions(account);
            }
        });
        contentPanel.add(chckbxStartDate);

        chckbxEndDate = new JCheckBox("End Date:");
        chckbxEndDate.setBounds(6, 33, 89, 23);
        chckbxEndDate.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if(chckbxEndDate.isSelected())
                {
                    comboEndMonth.setEnabled(true);
                    comboEndDay.setEnabled(true);
                    comboEndYear.setEnabled(true);
                }
                else
                {
                    comboEndMonth.setEnabled(false);
                    comboEndDay.setEnabled(false);
                    comboEndYear.setEnabled(false);
                }

                listTransactions(account);
            }
        });
        contentPanel.add(chckbxEndDate);

        listTransactions(account);
    }

    private void listTransactions(BankAccount account)
    {       
        LocalDateTime startTime;
        LocalDateTime endTime;
        String startMonthName = (String) comboStartMonth.getSelectedItem();
        int startDay = (int) comboStartDay.getSelectedItem();
        int startYear = (int) comboStartYear.getSelectedItem();
        String endMonthName = (String) comboEndMonth.getSelectedItem();
        int endDay = (int) comboEndDay.getSelectedItem();
        int endYear = (int) comboEndYear.getSelectedItem();

        if(chckbxStartDate.isSelected())
        {
            int startMonth = Month.valueOf(startMonthName.toUpperCase()).getValue();    

            try
            {
                startTime = LocalDateTime.of(startYear, startMonth, startDay, 0, 0);
            }
            catch(DateTimeException e)
            {
                txtTransactions.setText("INVALID DATE");
                return;
            }
        }
        else
        {
            startTime = null;
        }

        if(chckbxEndDate.isSelected())
        {
            int endMonth = Month.valueOf(endMonthName.toUpperCase()).getValue();

            try
            {
                endTime = LocalDateTime.of(endYear, endMonth, endDay, 23, 59);
            }
            catch(DateTimeException e)
            {
                txtTransactions.setText("INVALID DATE");
                return;
            }
        }
        else
        {
            endTime = null;
        }

        ArrayList<Transaction> transactionList = account.getTransactions(startTime, endTime);
        String output = "";
        int maxAmountDigits = 1;

        for(Transaction t : transactionList)
        {
            String stringAmount = String.format("%.2f", t.getAmount());

            if(stringAmount.length() > maxAmountDigits)
                maxAmountDigits = stringAmount.length();
        }

        output += String.format("%-10s %-8s %-" + (maxAmountDigits + 1) + "s %s
", "Date", "Time", "Amount", "Description");   
        //https://stackoverflow.com/questions/37791455/java-string-format-adding-spaces-to-integers
        output += String.format("%0" + 100 + "d
", 0).replace("0", "-");

        for(Transaction t : transactionList)
        {
            output += String.format("%d.%02d.%02d %02d:%02d:%02d $%-" + maxAmountDigits + ".2f %s
", t.getTransactionTime().getYear(),
                                                                                                      t.getTransactionTime().getMonthValue(),
                                                                                                      t.getTransactionTime().getDayOfMonth(),
                                                                                                      t.getTransactionTime().getHour(),
                                                                                                      t.getTransactionTime().getMinute(),
                                                                                                      t.getTransactionTime().getSecond(),
                                                                                                      t.getAmount(),
                                                                                                      t.getDescription());
        }

        txtTransactions.setText(output);
    }
}
答案
contentPanel.setLayout(null);

首先,将布局设置为null:

    JScrollPane txtTScrollPane = new JScrollPane(txtTransactions);
    contentPanel.add(txtTScrollPane);
    //contentPanel.revalidate();
    //contentPanel.repaint();

然后将滚动窗格添加到内容面板。但是,您没有在滚动窗格上使用setBounds(),并且组件的默认大小为(0,0),因此无需绘制任何内容。

但是,解决方案不是添加setBounds(...)。解决方案是不使用null布局。使用null布局看起来似乎更容易,但是当你在滚动窗格中使用时,你会遇到这样的问题并且组件无法正常工作。

所以正确的解决方案是修复你的代码并使用Layout Managers。 Swing旨在与布局管理器一起使用。然后布局管理器将设置组件的大小和位置,因此您不必担心它。

revalidate()和repaint()仅在将组件添加到可见GUI以调用布局管理器时使用,因此不需要它们。

此外,在创建文本区域时,请执行以下操作:

//txtTransactions = new JTextArea();
txtTransactions = new JTextArea(5, 20);

这将使文本区域根据文本区域的行/列和字体确定其自己的首选大小。然后布局管理员可以做得更好。

以上是关于JScrollPane没有出现的主要内容,如果未能解决你的问题,请参考以下文章

JScrollPane添加到JFrame中,怎么不显示呢?

JScrollPane 组件不出现

如何将 jscrollpane 添加到 jframe?

JScrollPane 上面放 JPanel 怎么让 JScrollPane 在适当的时候显示滚动条

Java Swing通过拖动滚动JScrollPane

JScrollPane