Как я могу рассчитать и сохранить только то, что видно в JTable? - PullRequest
0 голосов
/ 05 августа 2020

РЕДАКТИРОВАТЬ: По совету camickr, я сделал пару простых правок в этот демонстрационный код:


/*
 * TableDemo.java requires no other files.
 */

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

/** 
 * TableDemo is just like SimpleTableDemo, except that it
 * uses a custom TableModel.
 */
public class TableDemo extends JPanel {
    private boolean DEBUG = false;

    public TableDemo() {
        super(new GridLayout(1,0));

        JTable table = new JTable(new MyTableModel());
        table.setPreferredScrollableViewportSize(new Dimension(500, 70));
        table.setFillsViewportHeight(true);

        //Create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        //Add the scroll pane to this panel.
        add(scrollPane);
    }

    class MyTableModel extends AbstractTableModel {
        private String[] columnNames = {"Seconds Since Epoch",
                                        "Formatted Timestamp"};

        public int getColumnCount() {
            return columnNames.length;
        }

        public int getRowCount() {
            return Integer.MAX_VALUE;
        }

        public String getColumnName(int col) {
            return columnNames[col];
        }

        public Object getValueAt(int row, int col) {
            if (col == 0) {
                return row;
            }

            return getPrettyStringFromEpochSeconds((long) row);
        }

        private String getPrettyStringFromEpochSeconds(long seconds) {
            LocalDateTime dateTime = LocalDateTime.ofEpochSecond(seconds, 0, ZoneOffset.UTC);
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("h:mm:ss a EEEE, MMMM d, yyyy", Locale.ENGLISH);
            String formattedDate = dateTime.format(formatter);
            return formattedDate;
        }

        /*
         * JTable uses this method to determine the default renderer/
         * editor for each cell.  If we didn't implement this method,
         * then the last column would contain text ("true"/"false"),
         * rather than a check box.
         */
        public Class getColumnClass(int c) {
            return c == 0 ? Integer.class : String.class;
        }

    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("TableDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        TableDemo newContentPane = new TableDemo();
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

Я думаю, это работает, но я не могу прокрутить вниз и узнай. Есть идеи, почему добавленная полоса прокрутки на самом деле ничего не делает?

| ------------------------------ -------------------------------------------------- -------------------------------------------------- |

Итак, я хочу создать JTable с двумя столбцами: один, содержащий возрастающие числа от 0 (без верхней границы!), А другой столбец, содержащий строку, которую я получаю из числа в той же строке. Поскольку технически эта таблица имеет бесконечный размер, я хотел бы вычислять и отображать только столько строк, сколько умещается на экране, и изменять значения таблицы на основе вертикальной полосы прокрутки. Например, если размер окна в настоящее время такой, что на экране помещаются только 3 строки, я хочу, чтобы таблица выглядела так:

|---------------------|------------------|
|      Heading 1      |     Heading 2    |
|---------------------|------------------|
|          0          |       Str0       |
|---------------------|------------------|
|          1          |       Str1       |
|---------------------|------------------|
|          2          |       Str2       |
|---------------------|------------------|

Но после прокрутки вниз на одну строку я хочу, чтобы она выглядела так :

|---------------------|------------------|
|      Heading 1      |     Heading 2    |
|---------------------|------------------|
|          1          |       Str1       |
|---------------------|------------------|
|          2          |       Str2       |
|---------------------|------------------|
|          3          |       Str3       |
|---------------------|------------------|

Существует ли относительно простой способ динамического вычисления и рендеринга этих значений, чтобы объем моей памяти масштабировался с размером экрана, а не с размером моего набора данных?

1 Ответ

0 голосов
/ 07 августа 2020

Вы не можете установить количество строк на Integer.MAX_VALUE. Наибольшее число сработавших было 65536 * 2048 - 1.

Вот код, который я запустил.

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

/**
 * TableDemo is just like SimpleTableDemo, except that it uses
 * a custom TableModel.
 */
public class TableDemo extends JPanel {

    private static final long serialVersionUID = 1L;

//  private boolean DEBUG = false;

    public TableDemo() {
        super(new BorderLayout());

        JTable table = new JTable(new MyTableModel());
        table.setPreferredScrollableViewportSize(
                new Dimension(500, 16 * 10));
        table.setFillsViewportHeight(true);

        // Create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);
        scrollPane.setVerticalScrollBarPolicy(
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        // Add the scroll pane to this panel.
        add(scrollPane);
    }

    class MyTableModel extends AbstractTableModel {
        private static final long serialVersionUID = 1L;

        private String[] columnNames = { "Seconds Since Epoch",
                "Formatted Timestamp" };

        @Override
        public int getColumnCount() {
            return columnNames.length;
        }

        @Override
        public int getRowCount() {
            return 65536 * 2048 - 1;
        }

        @Override
        public String getColumnName(int col) {
            return columnNames[col];
        }

        @Override
        public Object getValueAt(int row, int col) {
            if (col == 0) {
                return row;
            }

            return getPrettyStringFromEpochSeconds(row);
        }

        private String getPrettyStringFromEpochSeconds(long seconds) {
            LocalDateTime dateTime = LocalDateTime.ofEpochSecond(
                    seconds, 0, ZoneOffset.UTC);
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
                    "h:mm:ss a EEEE, MMMM d, yyyy", Locale.ENGLISH);
            String formattedDate = dateTime.format(formatter);
            return formattedDate;
        }

        /*
         * JTable uses this method to determine the default
         * renderer/ editor for each
         * cell. If we didn't implement this method, then
         * the last column would contain
         * text ("true"/"false"), rather than a check box.
         */
        @Override
        public Class<?> getColumnClass(int c) {
            return c == 0 ? Integer.class : String.class;
        }

    }

    /**
     * Create the GUI and show it. For thread safety, this method
     * should be invoked from the event-dispatching thread.
     */
    private static void createAndShowGUI() {
        // Create and set up the window.
        JFrame frame = new JFrame("TableDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Create and set up the content pane.
        TableDemo newContentPane = new TableDemo();
        // content panes must be opaque
        newContentPane.setOpaque(true);
        frame.setContentPane(newContentPane);

        // Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        // Schedule a job for the event-dispatching thread:
        // creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...