2

カスタム選択モードを含むJTablecustomがあります。ListSelectionModelこの選択モードでは、選択は 1 つの行でのみ行われますが、複数のセルが含まれます。ユーザーがテーブル内のいくつかのセルをクリックして選択すると、選択されたセルはすべて、最初に選択されたセルと同じ行になります。

ここで、主要な選択セルの右上隅の上に小さなメッセージを作成したいと思います。このメッセージには、選択されたセルの数などのデータが表示されます。先頭の選択が変更されたときに、メッセージを移動する必要があります。

しかし、どうすればそれを行うことができますか?これは、ユーザーがテーブルをクリックしてセルを選択したときに表示されることを意図しているため、ツールチップではありません。

助言がありますか?

よろしく、htz

4

3 に答える 3

3

あるいは (あまりきれいではありませんが、うまく機能します)、JTable が他のすべてのコンポーネントと同様に JComponent であるという事実を利用して、それに子コンポーネントを追加することもできます。あなたがしなければならないことは、コンポーネントのサイズと位置を適切に設定することだけです (これは、JTable が null レイアウトを使用するためです)。

これは、選択された項目の数を表示する JLabel を使用した小さなデモです。ラベルは、最初の表示されている行に自動的に配置されますが、それが現在のリードの選択ではない場合、ラベルは 2 番目の表示されている行に移動されます。

import java.awt.BorderLayout;
import java.awt.Point;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class TestTable {

    protected void initUI() {
        Vector<Vector<Object>> data = new Vector<Vector<Object>>();
        Vector<String> colNames = new Vector<String>();
        for (int i = 0; i < 5; i++) {
            colNames.add("Col-" + (i + 1));
        }
        for (int i = 0; i < 200; i++) {
            Vector<Object> row = new Vector<Object>();
            for (int j = 0; j < 5; j++) {
                row.add("Cell " + (i + 1) + "-" + (j + 1));
            }
            data.add(row);
        }
        table = new JTable(data, colNames);
        someText = new JLabel();
        someText.setOpaque(true);
        table.add(someText);
        table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

            @Override
            public void valueChanged(ListSelectionEvent e) {
                int count = table.getSelectedRowCount();
                someText.setText("You currently have selected " + count + " item" + (count > 1 ? "s" : ""));
                layoutLabel();
            }
        });
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        scrollpane = new JScrollPane(table);
        scrollpane.getViewport().addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                layoutLabel();
            }
        });
        frame.add(scrollpane, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
    }

    private JLabel someText;
    private JTable table;
    private JScrollPane scrollpane;

    private void layoutLabel() {
        someText.setSize(someText.getPreferredSize());
        Point location = scrollpane.getViewport().getViewRect().getLocation();
        int leadSelectionIndex = table.getSelectionModel().getLeadSelectionIndex();
        if (leadSelectionIndex > -1) {
            if (table.rowAtPoint(location) == leadSelectionIndex) {
                location.y += table.getRowHeight(leadSelectionIndex);
            }
        }
        someText.setLocation(location);
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestTable().initUI();
            }
        });
    }

}
于 2012-10-01T13:37:15.380 に答える
2

さらに別のオプションは、以下に示すように、コンポーネントごとの glassPane (1.7 の場合は JLayer、1.6 の場合は JXLayer の多くの役割の 1 つ) を実装することです。@Guillaumeが行ったように、場所をきれいにしようとしなかったことに注意してください。また、Rob の DragLayout を少し変更して、ボックスがテーブル領域内に表示されるようにする必要があります。

public static class ToolTipUI extends LayerUI<JTable> {
    private JLayer<JTable> layer;
    private JToolTip toolTip;

    @Override
    public void installUI(JComponent c) {
        super.installUI(c);
        this.layer = (JLayer) c;
        installGlassPane();
        installListeners();
    }

    private void installListeners() {
        ListSelectionListener l = new ListSelectionListener() {

            @Override
            public void valueChanged(ListSelectionEvent e) {
                if (e.getValueIsAdjusting()) return;
                updateToolTip();
            }

        };
        getTable().getColumnModel().getSelectionModel().addListSelectionListener(l);
        getTable().getSelectionModel().addListSelectionListener(l);
    }

    private void updateToolTip() {
        int[] selectedColumns = getTable().getColumnModel().getSelectedColumns();
        int selectedRow = getTable().getSelectedRow();
        if (selectedRow < 0 || selectedColumns.length == 0) {
            setToolTipText("");
        } else {
            String text = "selected cells: ";
            for (int i = 0; i < selectedColumns.length; i++) {
                text += " " + selectedColumns[i];
            }
            setToolTipText(text);
        }
    }

    private void setToolTipText(String string) {
        toolTip.setTipText(string);
        Rectangle cellBounds = getTable().getCellRect(getTable().getSelectedRow(), 0, false);
        toolTip.setLocation(cellBounds.getLocation());
        doLayout(layer);
    }

    @Override
    public void doLayout(JLayer<? extends JTable> l) {
        super.doLayout(l);
        l.getGlassPane().doLayout();
    }

    private JTable getTable() {
        return layer.getView();
    }

    private void installGlassPane() {
        toolTip = ((JComponent) layer.getView()).createToolTip();
        layer.getGlassPane().setBorder(BorderFactory.createLineBorder(Color.RED));
        // DragLayout by Rob Camick http://tips4java.wordpress.com/2011/10/23/drag-layout/
        layer.getGlassPane().setLayout(new DragLayout());
        layer.getGlassPane().add(toolTip);
        layer.getGlassPane().setVisible(true);
    }

}

// usage:
JTable table = new JTable(new AncientSwingTeam());
JLayer layer = new JLayer<JTable>(table, new ToolTipUI());
于 2012-10-01T13:58:22.540 に答える
2
  • MsExcellのようにsimilair効果でToolTipLocations設定できますが、

これはツールチップではありません。ユーザーがテーブルをクリックしてセルを選択したときに表示されることを意図しており、カーソルをその上に置いたときではありません。

  • non_editableコンテンツには、の代わりにJPopup/を使用できますJWindowToolTip

  • JPopup/JWindowデフォルトでは、編集可能なものを含めることはできませんJComponent( JTextComponents)

  • ユーザー入力には、装飾されていないものJDialodのみを使用できます

于 2012-10-01T12:30:52.517 に答える