[は、Java Swing] JListをカスタマイズ – JListのカスタムレンダラ
全部で JListの 我々はいくつかの簡単な操作とイベントでJListを作成する方法を知っている. この記事では、私達のに応じて要素のリストを作成するJListをカスタマイズする方法を学び続け. 例えば、電話帳 (画像, 連絡先, 電話番号) お気に入りの本のリストまたは (カバーを含む, タイトル, 著者名) 下に示すように:

最初の情報ブックブックを保存するためのクラスを作成してみましょう. この3本のclass属性での名前です。, 著者と本のタイトル初期化メソッドをカバー, ゲッター, 以下のセッター:
package nguyenvanquan7826.JList;
public class Book {
private String name;
private String author;
private String iconName;
public Book(String name, String author, String iconName) {
super();
this.name = name;
this.author = author;
this.iconName = iconName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getIconName() {
return iconName;
}
public void setIconName(String iconName) {
this.iconName = iconName;
}
}
次に、作成 JFrameの 私たちの本のリストが表示されます. Aを含むJFrameの中で JPanelの メインパネルLÀ, このJPanelの含む 1 JListのはlistBookです, listBookは中に入れ 1 JScrollPaneのは、上下にスクロールすることができるとする例の長いリストダウン, JListのは、すべてが表示されません.
package nguyenvanquan7826.JList;
import java.awt.BorderLayout;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;
public class JListCustomRenderer extends JFrame {
private int width = 350;
private int height = 200;
private JList<Book> listBook;
public JListCustomRenderer() {
// add main panel
add(createMainPanel());
// set display
setTitle("JLIstCustomRenderer");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(width, height);
setLocationRelativeTo(null);
setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(new EmptyBorder(10, 10, 10, 10));
// create list book and set to scrollpane and add to panel
panel.add(new JScrollPane(listBook = createListBooks()),
BorderLayout.CENTER);
return panel;
}
private JList<Book> createListBooks() {
// create List model
DefaultListModel<Book> model = new DefaultListModel<>();
// add item to model
model.addElement(new Book("C/C++ Programming", "A", "cpp"));
model.addElement(new Book("Java Programming", "B", "java"));
model.addElement(new Book("C# Programming", "C", "cs"));
model.addElement(new Book("IOS Programming", "D", "ios"));
model.addElement(new Book("Windows Phone Programming", "E", "wp"));
model.addElement(new Book("Android Programming", "F", "android"));
// create JList with model
JList<Book> list = new JList<Book>(model);
return list;
}
public static void main(String[] args) {
new JListCustomRenderer();
}
}
よくやった, だから我々は本のリストを持っており、, 実行プログラムは、何を参照するにはそれ? それは、この外だ=)) 驚き, すべてにおいて所望しない@@

なぜ、そのような, 我々は、名前と作者の名前が含まれている書籍のリストに追加した, では、なぜこのプログラムは、表示する? 実際、JListのは介して処理される モデルリスト と呼ばれるオブジェクトによって実行JListのショーのオブジェクトを促進 レンダラー 各JListのでは、デフォルトのレンダラを持つ. これがどのように動作するので、デフォルトのレンダリング? レンダラは、JListの内の要素を表示するための責任を負う. これは、メソッドを呼び出すことによって行われます のtoString() JListの対象とチェーンに入れては現れることを得る. そして、Bookクラスによって、我々は、スレッドのtoStringを書いていない() レンダラは、その文字列のtoStringをとっている必要があります() クラスBookのデフォルト. そして、我々はプログラムで取得チェーンだけでなく、文字列は、どのシステムがJListのブック内の各オブジェクトを提供.
今、私たちはのtoStringをオーバーライドしてみてください() 以下のクラスの予約:
@Override
public String toString() {
return name + " - " + author;
}
私たちは、のtoStringをオーバーライド() 本の名前と著者を返すように. あなたがプログラムを実行するとだから我々はこのようなリストを取得:

それは我々が着実に見てきたように見え、? いいえ、彼らはしなければならない! 我々は、それがそうする必要があり、開口部のイメージとしてカバーを示す必要がある? 我々はすべてのJListがレンダラーによって表示されている知っているように、あなたはそれを変更したい場合に応じてJListのレンダラを書き換えることにより、絶対的に容易である私たちの.
それでは、決定させるかどうかJListのあるものの各要素? ここでは、それが3を含むJPanelのようにしたい JLabelの, JLabelのは、カバーのフォトブックです, JLabelのJLabelの名前と最後の本は著者の名前が青色である.
カスタマイズ可能なレンダラに我々は再び呼ばれる別のクラスを記述します BookRendererはJPanelのを継承. また、このクラスには名前が必要なインターフェイスを実装 ListCellRenderer. このインタフェースは、メソッドを持って getListCellRendererComponent() 私たちの主のJPanelに戻り、それがJListを表示するために処理される.
package nguyenvanquan7826.JList;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
public class BookRenderer extends JPanel implements ListCellRenderer<Book> {
private JLabel lbIcon = new JLabel();
private JLabel lbName = new JLabel();
private JLabel lbAuthor = new JLabel();
public BookRenderer() {
setLayout(new BorderLayout(5, 5));
JPanel panelText = new JPanel(new GridLayout(0, 1));
panelText.add(lbName);
panelText.add(lbAuthor);
add(lbIcon, BorderLayout.WEST);
add(panelText, BorderLayout.CENTER);
}
@Override
public Component getListCellRendererComponent(JList<? extends Book> list,
Book book, int index, boolean isSelected, boolean cellHasFocus) {
lbIcon.setIcon(new ImageIcon(getClass().getResource(
"/nguyenvanquan7826/JList/" + book.getIconName() + ".jpg")));
lbName.setText(book.getName());
lbAuthor.setText(book.getAuthor());
lbAuthor.setForeground(Color.blue);
return this;
}
}
JListの各要素はJPanelのです. これはBorderLayoutのレイアウトJPanelのです, それは西のアイコンが含まれています (WEST) とpanelText. panelTextは2 JLabelのタイトルと著者名を含むJPanelのです.
私たちは、メソッド内のJLabelのテキストとアイコンを設定getListCellRendererComponent(). この方法は、本書籍、テレビでクラスのオブジェクトを取る. 本書の主な目的は、それが表示される要素であるのJList. だから我々は、アイコンを置く, 服用のiconNameを通じてJLabelのテキストの, 名前, この本のオブジェクトの作成者.
今、私たちは戻ってcreateListBookは次のようにJListCustomRendererクラスメソッドを改訂:
private JList<Book> createListBooks() {
// create List model
DefaultListModel<Book> model = new DefaultListModel<>();
// add item to model
model.addElement(new Book("C/C++ Programming", "A", "cpp"));
model.addElement(new Book("Java Programming", "B", "java"));
model.addElement(new Book("C# Programming", "C", "cs"));
model.addElement(new Book("IOS Programming", "D", "ios"));
model.addElement(new Book("Windows Phone Programming", "E", "wp"));
model.addElement(new Book("Android Programming", "F", "android"));
// create JList with model
JList<Book> list = new JList<Book>(model);
// set cell renderer
list.setCellRenderer(new BookRenderer());
return list;
}
今すぐプログラムを実行すると、希望のJListのようになります。.

しかし未完. あなたは私達が項目をクリックしたときに、彼らは何も@@現象が表示されていないことに気づいた. 私たちはこれ以上作成するレンダラレンダラデフォルト効果を書き換える必要があるためです (背景色選択 1 アイテム). 私たちは、JPanelのための背景色を設定します, 次のように選択したかどうかを選択したJLabelのための (メソッドを記述getListCellRendererComponent() クラスBookRendererの)
@Override
public Component getListCellRendererComponent(JList<? extends Book> list,
Book book, int index, boolean isSelected, boolean cellHasFocus) {
lbIcon.setIcon(new ImageIcon(getClass().getResource(
"/nguyenvanquan7826/JList/" + book.getIconName() + ".jpg")));
lbName.setText(book.getName());
lbAuthor.setText(book.getAuthor());
lbAuthor.setForeground(Color.blue);
// set Opaque to change background color of JLabel
lbName.setOpaque(true);
lbAuthor.setOpaque(true);
lbIcon.setOpaque(true);
// when select item
if (isSelected) {
lbName.setBackground(list.getSelectionBackground());
lbAuthor.setBackground(list.getSelectionBackground());
lbIcon.setBackground(list.getSelectionBackground());
setBackground(list.getSelectionBackground());
} else { // when don't select
lbName.setBackground(list.getBackground());
lbAuthor.setBackground(list.getBackground());
lbIcon.setBackground(list.getBackground());
setBackground(list.getBackground());
}
return this;
}
それでおしまい, 今、私たちは実行してから、項目を選択することができます.

ごく一部であり、本の表紙画像が互いに比較的近いと思われることである? 我々は、記事のオフラインの上部にある形状のようないくつかの美しい分離しない, それはあなたが行うことができることを意味 (lbIconを置くことを提案し 1 空のボーダのJPanelとすることをJPanelを設定する).
パッケージには、こちらからダウンロードできます カスタムJListの

での記事を参照する: codejava.net



私に聞いてみましょう, ラベルを取ります, イメージアイコン, どのように先生を書面でのJRadioButton配列のJList. 私はラジオボタンを選択することはできませんので
これだけでは明確ではありませんでした.
兄は私に尋ねました :
メソッドを持っていlist.setCellRenderer(新しいBookRenderer());
それは、クラスBookRenderer対レンダラーオブジェクトをリセット()
しかし、メソッドを呼び出すことはありませんgetListCellRendererComponent()
それはどのように右のDCを表示することができます ?
我々はJListのから複数の項目を選択することができますどのように依頼する広告, 選択されたものだけにするJListです 1 アイテム
あなたはグーグルを検索してみてください “多言語項目のJList NHEを選択”
このラインでのスター、それのjava.lang.NullPointerExceptionエラー:
lbIcon.setIcon(新しいイメージアイコン(のgetClass().のgetResource(
“/nguyenvanquan7826 / JListの/” + book.getIconName() + “.JPG”)));
この機能ではライン上:
公共コンポーネントgetListCellRendererComponent();
あなたはまだ正しいフォルダパスに軽量の画像を見ます. それがまだ失敗する場合は、ここで修正する方法を見ることができます: https://cachhoc.net/san-pham/