سؤال

هل هناك طريقة سهلة لمعالجة عناصر التحكم في JTable لاعطاء وظائف مختلفة عندما يكون هناك زر لوحة المفاتيح الضغط على (زر أي. CTRL) ويتم تحديد صف واحد؟ لقد طلب مني لإنشاء جدول حيث CTRL + انقر على (زر الماوس) على التوالي وإلغاء تحديد فقط الصف المحدد، أبدا تحديد صف. إذا كان المستخدم CTRL + نقرات صف غير محددة، لن يحدث شيء.

ولقد كنت قادرا على إنشاء جدول، وظائف تعطيل مثل CTRL + A (تحديد كافة)، ولقد كنت قادرا على معرفة ما اذا كان الضغط على زر التحكم عندما يتم إنشاء MouseEvent، ولكن لا أستطيع يبدو لمعرفة كيف يمكن تعديل CTRL + النقر. وإليك بعض التعليمات البرمجية:

package nicky;

import javax.swing.*;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.*;

public class TableTester extends JPanel {
    public TableTester() {
        super(new GridLayout(1,0));

        final String[] columnNames = {"First Name",
                                      "Last Name",
                                      "Sport",
                                      "# of Years",
                                      "Vegetarian"};

        final Object[][] data = {
            {"Tom",   "Roberts","Athletic", new Integer(5),  new Boolean(false)},
            {"Sarah", "Watt",   "Football", new Integer(3),  new Boolean(true)},
            {"Laura", "Brown",  "Swimming", new Integer(2),  new Boolean(false)},
            {"Simon", "Smith",  "Tennis",   new Integer(20), new Boolean(true)},
            {"Paul",  "Jones",  "Rugby",    new Integer(10), new Boolean(false)}
        };

        JTable table = new JTable(data, columnNames);
        table.setPreferredScrollableViewportSize(new Dimension(500, 100));

        table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

        table.addMouseListener(new MouseListener(){
            public void mouseEntered(MouseEvent me){}
            public void mouseExited(MouseEvent me){}
            public void mouseReleased(MouseEvent me){}
            public void mouseClicked(MouseEvent me){}
            public void mousePressed(MouseEvent me){
                if (me.isControlDown()){
                    System.out.println("This is working ");
                }
            }
        });

        InputMap inputMap = table.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_MASK);
        inputMap.put(keyStroke, "none");

        JScrollPane scrollPane = new JScrollPane(table);
        add(scrollPane);
    }

    private static void createAndShowGUI() {
        JFrame.setDefaultLookAndFeelDecorated(true);
        JFrame frame = new JFrame("TableTester");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        TableTester newContentPane = new TableTester();
        newContentPane.setOpaque(true);
        frame.setContentPane(newContentPane);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

في طريقة mousePressed لقد لعبت حوالي مع الحصول على جميع الصفوف المحددة من الجدول، وبعد ذلك يذهب للتحقق مما إذا كان الصف النقر حديثا في selectedRows ... ومع ذلك، أنا لست متأكدا إذا كان هناك وسيلة لرؤية الصف الذي يرتبط مع MouseEvent.

و(أيضا، وأنا أعلم سلوك متوقع مثل هذا لا ينبغي أن يكون لعبت مع حولها كثيرا، لكنه لتكرار نظام الإرث في الشركة)

وأي أفكار / اقتراحات سيكون موضع تقدير!

هل كانت مفيدة؟

المحلول

وOK، تأخذ الثاني (غادرت أول واحد لأنها قد تثير شخص ما لبعض الاستخدامات الأخرى الذين يعرفون قلها هناك لأغراض تعليمية ...: -؟)).

وكان لي نظرة على شفرة المصدر من JTable وتبين أن يتم التعامل مع أحداث الماوس عن طريق الشكل والمظهر. معرفة كيف يتعامل مع مفتاح التحكم، ويمكنني أن تجاوز بأمان طريقة changeSelection لتفعل ما تريد.
أجد متطلبات غريبة بعض الشيء (لا يزال بإمكانك استخدام مفتاح Shift + فوق، أليس كذلك؟)، ولكن أنا لا أعرف السياق.

class SpecialTable extends JTable
{
    SpecialTable(Object[][] data, String[] columnNames)
    {
        super(data, columnNames);
// That's already the default        
//        setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    }

    /**
     * Called by javax.swing.plaf.basic.BasicTableUI.Handler.adjustSelection(MouseEvent)
     * like: table.changeSelection(pressedRow, pressedCol, e.isControlDown(), e.isShiftDown());
     */
    @Override
    public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend)
    {
        if (toggle && !isRowSelected(rowIndex))
            return; // Don't do the selection
        super.changeSelection(rowIndex, columnIndex, toggle, extend);
    }
}

والكثير بساطة وبالضبط ما تحتاجه!

وراجع للشغل، وذلك بفضل لتقديم مثل هذه بسيطة اختبارا جيدا، وأنا ربما لم يحاكم إذا كان لي أن أكتب بنفسي ... :-D كان تحديا مثيرا للاهتمام والتعلم.

نصائح أخرى

وكان لي النجاح مع ما يلي، على الرغم من أنني لست متأكدا من أن هذا هو أفضل طريقة ...

class SpecialTable extends JTable
{
    boolean bIsControlDown;
    int clickedRow;

    SpecialTable(Object[][] data, String[] columnNames)
    {
        super(data, columnNames);
//        setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        getSelectionModel().addListSelectionListener(this);
        addMouseListener(new MouseInputAdapter()
        {
            public void mousePressed(MouseEvent me)
            {
                bIsControlDown = me.isControlDown();
                clickedRow = rowAtPoint(me.getPoint());
            }
        });
    }

    public void valueChanged(ListSelectionEvent evt)  
    {
        super.valueChanged(evt);
        if (bIsControlDown)
        {
            if (!evt.getValueIsAdjusting())
            {
//                System.out.println(evt);
//                System.out.println("=> " + clickedRow);
                getSelectionModel().removeSelectionInterval(clickedRow, clickedRow);
            }
        }
    }
}

واستبدال خطوط تحديد table في التعليمات البرمجية مع فقط:

    JTable table = new SpecialTable(data, columnNames);
    table.setPreferredScrollableViewportSize(new Dimension(500, 100));

عند يمكنك التحكم مزدوجا فوق صف غير محددة، يتم تحديده لفترة وجيزة، ثم غير محددة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top