Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException
вообще.
См. также: A хороший список лучших практик
Я бы добавил, очень важно, хорошо использовать модификатор final
. Использование "окончательной" модификатор, когда это применимо в Java
Сводка:
final
для обеспечения хорошей инициализации. @NotNull
и @Nullable
if("knownObject".equals(unknownObject)
valueOf()
поверх toString (). StringUtils
StringUtils.isEmpty(null)
. Для этого я в настоящее время добавляю их в другой JPanel и устанавливаю эту панель как область просмотра scrollPane.
blockquote>Не совсем. Вы не делали бы контейнер JPanel в окне просмотра, а скорее вид viewport. Сам видовой порт является очень специализированным контейнером со своим собственным менеджером компоновки, и это было бы испорчено, если бы вы просто заменили его на JPanel.
, т. Е.
JViewport viewport = myScrollPane.getViewport(); viewport.setView(myContainerJPanel);
или более кратко
myScrollPane.setViewportView(myContainerJPanel);
Обратите внимание, что это меня беспокоит:
x.setLocation(0, 45 *i);
и предлагает использовать макетыnull
где-то. Независимо от того, что вы делаете, не делайте этого, не используйте макетыnull
, особенно в JScrollPanes, так как это все испортит.
Для получения более подробной справки подумайте о создании и публикации sscce или [минимальный пример программы] program / mcve , где вы сконденсируете свой код на самый маленький бит, который все еще компилируется и запускается, не имеет внешних зависимостей (например, необходимо связать базу данных или изображения), не имеет дополнительного кода, который не имеет отношения к вашей проблеме, но все еще демонстрирует вашу проблему. Также рассмотрите размещение изображения нужного вам результата.
Например:
import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridBagLayout; import java.awt.GridLayout; import javax.swing.*; public class ScrollPaneEg extends JPanel { private static final int PREF_W = 480; private static final int PREF_H = PREF_W; public ScrollPaneEg() { JScrollPane scrollPane = new JScrollPane(); scrollPane.setViewportBorder(null); scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); JPanel container = new JPanel(new GridLayout(0, 1)); // 1 column variable // number of rows for (int i = 0; i < 15; i++) { SingleClientPanel x = new SingleClientPanel(String.valueOf(i + 1)); // x.setLocation(0, 45 *i); container.add(x); } scrollPane.setViewportView(container); setLayout(new BorderLayout()); add(scrollPane, BorderLayout.CENTER); } @Override public Dimension getPreferredSize() { if (isPreferredSizeSet()) { return super.getPreferredSize(); } return new Dimension(PREF_W, PREF_H); } private static void createAndShowGui() { ScrollPaneEg mainPanel = new ScrollPaneEg(); JFrame frame = new JFrame("ScrollPaneEg"); 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(); } }); } } class SingleClientPanel extends JPanel { private static final int PREF_H = 60; public SingleClientPanel(String text) { setBorder(BorderFactory.createTitledBorder("Single Client")); setLayout(new GridBagLayout()); add(new JLabel("Panel: " + text, SwingConstants.CENTER)); } @Override public Dimension getPreferredSize() { Dimension superSz = super.getPreferredSize(); if (isPreferredSizeSet()) { return superSz; } int prefH = Math.max(superSz.height, PREF_H); return new Dimension(superSz.width, prefH); } }
Кроме того, рассмотрите возможность использования JTable для отображения ваших табличных данных. Например, ...
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Window; import java.awt.event.*; import java.util.ArrayList; import java.util.List; import java.util.UUID; import javax.swing.*; import javax.swing.border.LineBorder; import javax.swing.table.AbstractTableModel; public class ClientOverviewTest { private static void createAndShowGui() { ClientOverviewPanel2 mainPanel = new ClientOverviewPanel2(); JFrame frame = new JFrame("ClientOverviewPanel"); 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(); } }); } } class ClientOverviewPanel2 extends JPanel { private static final int CLIENTS = 5; private static final int PREF_W = 600; private static final int PREF_H = 200; private ClientTableModel model = new ClientTableModel(); private JTable table = new JTable(model); public ClientOverviewPanel2() { for (int i = 0; i < CLIENTS; i++) { String ip = "127.000.000.001"; UUID uuid = UUID.randomUUID(); boolean isLocal = true; SingleClient client = new SingleClient(ip, uuid, isLocal); model.addRow(client); } table.getColumnModel().getColumn(1).setPreferredWidth(150); //!! table.setPreferredScrollableViewportSize(table.getPreferredSize()); JScrollPane scrollPane = new JScrollPane(table); scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); setLayout(new BorderLayout()); add(scrollPane, BorderLayout.CENTER); add(new JButton(new OkAction("OK")), BorderLayout.PAGE_END); } @Override public Dimension getPreferredSize() { Dimension superSz = super.getPreferredSize(); if (isPreferredSizeSet()) { return superSz; } int prefW = PREF_W; int prefH = Math.min(superSz.height, PREF_H); return new Dimension(prefW, prefH); } private class OkAction extends AbstractAction { public OkAction(String name) { super(name); int mnemonic = (int) name.charAt(0); putValue(MNEMONIC_KEY, mnemonic); } @Override public void actionPerformed(ActionEvent e) { Component source = (Component) e.getSource(); Window window = SwingUtilities.getWindowAncestor(source); if (window != null) { window.dispose(); } } } } class ClientTableModel extends AbstractTableModel { public final static String[] COLUMNS = { "IP", "UUID", "Local" }; private List<SingleClient> clientList = new ArrayList<>(); @Override public int getColumnCount() { return COLUMNS.length; } @Override public int getRowCount() { return clientList.size(); } @Override public String getColumnName(int column) { return COLUMNS[column]; } public void addRow(SingleClient client) { clientList.add(client); int index = clientList.size() - 1; fireTableRowsInserted(index, index); } @Override public Object getValueAt(int rowIndex, int columnIndex) { if (rowIndex >= getRowCount() || rowIndex < 0) { String text = "for rowIndex: " + rowIndex; throw new IllegalArgumentException(text); } if (columnIndex < 0 || columnIndex >= COLUMNS.length) { String text = "for columnIndex: " + columnIndex; throw new IllegalArgumentException(text); } SingleClient client = clientList.get(rowIndex); switch (columnIndex) { case 0: return client.getIp(); case 1: return client.getUuid(); case 2: return client.isLocal(); } return null; } @Override public Class<?> getColumnClass(int columnIndex) { if (columnIndex < 0 || columnIndex >= COLUMNS.length) { String text = "for columnIndex: " + columnIndex; throw new IllegalArgumentException(text); } switch (columnIndex) { case 0: return String.class; case 1: return UUID.class; case 2: return Boolean.class; } // default value return super.getColumnClass(columnIndex); } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return columnIndex == 2; } @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { SingleClient client = clientList.get(rowIndex); switch (columnIndex) { case 0: break; case 1: break; case 2: boolean isLocal = (boolean) aValue; client.setLocal(isLocal); default: break; } } } class SingleClient { private String ip; private UUID uuid; private boolean isLocal; public SingleClient(String ip, UUID uuid2, boolean isLocal) { this.ip = ip; this.uuid = uuid2; this.isLocal = isLocal; } public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } public UUID getUuid() { return uuid; } public void setUuid(UUID uuid) { this.uuid = uuid; } public boolean isLocal() { return isLocal; } public void setLocal(boolean isLocal) { this.isLocal = isLocal; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((ip == null) ? 0 : ip.hashCode()); result = prime * result + ((uuid == null) ? 0 : uuid.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; SingleClient other = (SingleClient) obj; if (ip == null) { if (other.ip != null) return false; } else if (!ip.equals(other.ip)) return false; if (uuid == null) { if (other.uuid != null) return false; } else if (!uuid.equals(other.uuid)) return false; return true; } }
Благодаря помощи я смог заставить ее работать. Я просто добавлю свое решение, включая изменения для справки и дальнейшие комментарии:
public class SingleClientPanel extends JPanel
{
private JTextField ipTextfield;
private JTextField uuidTextField;
public SingleClientPanel()
{
this("127.000.000.001",UUID.randomUUID().toString(),true);
}
public SingleClientPanel(String ip, String uuid,boolean isLocal)
{
/*
removed:
setSize(new Dimension(440, 35));
setPreferredSize(new Dimension(440, 35));
setMaximumSize(new Dimension(440, 35));
setMinimumSize(new Dimension(440, 35));*/
setBorder(new LineBorder(new Color(0, 0, 0), 1, true));
setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); // added this
ipTextfield = new JTextField();
ipTextfield.setHorizontalAlignment(SwingConstants.CENTER);
ipTextfield.setAlignmentX(Component.LEFT_ALIGNMENT);
ipTextfield.setFocusable(false);
ipTextfield.setEditable(false);
add(ipTextfield);
ipTextfield.setColumns(15);
ipTextfield.setText(ip);
uuidTextField = new JTextField();
uuidTextField.setHorizontalAlignment(SwingConstants.CENTER);
uuidTextField.setEditable(false);
uuidTextField.setFocusable(false);
add(uuidTextField);
uuidTextField.setColumns(30);
uuidTextField.setText(uuid);
JButton button = new JButton(">");
button.setEnabled(!isLocal);
add(button);
this.revalidate();
}
}
public class ClientOverviewPanel extends JPanel
{
public ClientOverviewPanel()
{
setLayout(new BorderLayout(0, 0));
JButton btnOk = new JButton("Ok");
btnOk.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
Window x = SwingUtilities.getWindowAncestor(ClientOverviewPanel.this);
if(x != null) x.dispose();
}
});
add(btnOk, BorderLayout.SOUTH);
JScrollPane scrollPane = new JScrollPane();
/*
removed:
scrollPane.setPreferredSize(new Dimension(480, 480));
scrollPane.setSize(new Dimension(480, 480));
scrollPane.setMinimumSize(new Dimension(480, 40));*/
scrollPane.setViewportBorder(null);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
Box box = new Box(BoxLayout.PAGE_AXIS); //added
for (int i=0; i<5;i++)
{
SingleClientPanel cpan = new SingleClientPanel();
//cpan.setLocation(0, 45 *i); removed
box.add(cpan); //changed
}
scrollPane.setViewportView(box); //changed
add(scrollPane, BorderLayout.CENTER);
this.revalidate();
}
}
x.setLocation(0, 45 *i);
и предлагает использовать макетыnull
где-то. Независимо от того, что вы делаете, не делайте этого, не используйте макетыnull
, особенно в JScrollPanes, так как это все испортит. – Hovercraft Full Of Eels 18 June 2015 в 12:56