Project received
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/out/
|
||||||
3
.idea/.gitignore
generated
vendored
Normal file
3
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
6
.idea/misc.xml
generated
Normal file
6
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="openjdk-18" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/livada.iml" filepath="$PROJECT_DIR$/livada.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
11
Derevia.in
Normal file
11
Derevia.in
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
10 4
|
||||||
|
Яблоко Яблоко Яблоко Яблоко
|
||||||
|
Яблоко Груша Вишня Персик
|
||||||
|
Яблоко Абрикос Вишня Слива
|
||||||
|
Яблоко Айва Слива Слива
|
||||||
|
Яблоко Слива Слива Слива
|
||||||
|
Яблоко Слива Слива Слива
|
||||||
|
Яблоко Слива Слива Слива
|
||||||
|
Яблоко Слива Слива Слива
|
||||||
|
Яблоко Слива Слива Слива
|
||||||
|
Яблоко Слива Слива Слива
|
||||||
10
Urojai.in
Normal file
10
Urojai.in
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
1.1 1.2 1.3 1.4
|
||||||
|
2.1 2.2 2.3 2.4
|
||||||
|
3.1 3.2 3.3 3.4
|
||||||
|
4.1 4.2 4.3 4.4
|
||||||
|
5.1 5.2 5.3 5.4
|
||||||
|
5.1 5.2 5.3 5.4
|
||||||
|
5.1 5.2 5.3 5.4
|
||||||
|
5.1 5.2 5.3 5.4
|
||||||
|
5.1 5.2 5.3 5.4
|
||||||
|
5.1 5.2 5.3 5.4
|
||||||
11
livada.iml
Normal file
11
livada.iml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
39
src/Data.java
Normal file
39
src/Data.java
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
public class Data {
|
||||||
|
private String tree;
|
||||||
|
private double harvest;
|
||||||
|
|
||||||
|
public Data(String tree, double harvest) {
|
||||||
|
this.tree = tree;
|
||||||
|
this.harvest = harvest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore data from table cell value
|
||||||
|
*
|
||||||
|
* @param data Value in JTable
|
||||||
|
*/
|
||||||
|
public Data(String data) {
|
||||||
|
String[] split = data.split("-");
|
||||||
|
this.tree = split[0].trim();
|
||||||
|
this.harvest = Double.parseDouble(split[1].trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTree() {
|
||||||
|
return tree;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getHarvest() {
|
||||||
|
return harvest;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("%s - %.3f", tree, harvest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println(new Data("Яблоко", 1.123));
|
||||||
|
System.out.println(new Data("Яблоко - 2.2345"));
|
||||||
|
System.out.println(new Data("Яблоко - 123456789.123456789"));
|
||||||
|
}
|
||||||
|
}
|
||||||
63
src/DataReader.java
Normal file
63
src/DataReader.java
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class DataReader {
|
||||||
|
public String[][] readTrees(String fileName) {
|
||||||
|
String[][] data;
|
||||||
|
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
|
||||||
|
String header = br.readLine();
|
||||||
|
String[] size = header.split(" ");
|
||||||
|
int n = Integer.parseInt(size[0]);
|
||||||
|
int m = Integer.parseInt(size[1]);
|
||||||
|
|
||||||
|
System.out.printf("Array size is %d x %d", n, m);
|
||||||
|
|
||||||
|
data = new String[n][m];
|
||||||
|
|
||||||
|
String line;
|
||||||
|
int row = 0;
|
||||||
|
while ((line = br.readLine()) != null) {
|
||||||
|
String[] trees = line.split(" ");
|
||||||
|
data[row++] = trees;
|
||||||
|
}
|
||||||
|
Arrays.toString(data);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double[][] readHarvest(String fileName, int rows) {
|
||||||
|
double[][] data = new double[rows][];
|
||||||
|
int row = 0;
|
||||||
|
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
|
||||||
|
String line;
|
||||||
|
while ((line = br.readLine()) != null) {
|
||||||
|
String[] s = line.split(" ");
|
||||||
|
double[] centners = new double[s.length];
|
||||||
|
for (int i = 0; i < s.length; i++) {
|
||||||
|
centners[i] = Double.parseDouble(s[i]);
|
||||||
|
}
|
||||||
|
data[row++] = centners;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Data[][] mergeData(String[][] trees, double[][] harvest) {
|
||||||
|
Data[][] result = new Data[trees.length][trees[0].length];
|
||||||
|
|
||||||
|
for (int row = 0; row < trees.length; row++) {
|
||||||
|
for (int col = 0; col < trees[0].length; col++) {
|
||||||
|
result[row][col] = new Data(trees[row][col], harvest[row][col]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
129
src/DataTableModel.java
Normal file
129
src/DataTableModel.java
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
|
||||||
|
public class DataTableModel extends AbstractTableModel {
|
||||||
|
|
||||||
|
private Data[][] rowData;
|
||||||
|
private String[] columnNames;
|
||||||
|
|
||||||
|
public DataTableModel(Data[][] rowData, String[] columnNames) {
|
||||||
|
this.rowData = rowData;
|
||||||
|
this.columnNames = columnNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Data[][] getRowData() {
|
||||||
|
return rowData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addColumn(int i) {
|
||||||
|
if (i > rowData[0].length) {
|
||||||
|
String message = String.format("Невозможно добавить столбец %d так как в таблце всего %d колонок", i, rowData[0].length);
|
||||||
|
JOptionPane.showMessageDialog(null, message, "Неправильный индекс столбца", JOptionPane.ERROR_MESSAGE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Data[][] newRowData = new Data[rowData.length][rowData[0].length + 1];
|
||||||
|
for (int row = 0; row < rowData.length; row++) {
|
||||||
|
for (int col = 0; col < rowData[0].length + 1; col++) {
|
||||||
|
if (col == i) {
|
||||||
|
newRowData[row][col] = new Data("", 0.);
|
||||||
|
} else if (col > i) {
|
||||||
|
newRowData[row][col] = rowData[row][col - 1];
|
||||||
|
} else {
|
||||||
|
newRowData[row][col] = rowData[row][col];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rowData = newRowData;
|
||||||
|
|
||||||
|
String[] newColumnNames = new String[columnNames.length + 1];
|
||||||
|
for (int col = 0; col < columnNames.length + 1; col++) {
|
||||||
|
newColumnNames[col] = col + 1 + "";
|
||||||
|
}
|
||||||
|
columnNames = newColumnNames;
|
||||||
|
|
||||||
|
this.fireTableDataChanged();
|
||||||
|
this.fireTableStructureChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
// public void removeColumn(int i) {
|
||||||
|
//
|
||||||
|
// Data colToDelete = columnNames.getColumnModel().getColumn(number);
|
||||||
|
// table.removeColumn(colToDelete);
|
||||||
|
// ColumnField.setText("");
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void addRow(int i) {
|
||||||
|
if (i > rowData[0].length) {
|
||||||
|
String message = String.format("Невозможно добавить строчку %d так как в таблце всего %d колонок", i, rowData[0].length);
|
||||||
|
JOptionPane.showMessageDialog(null, message, "Неправильный индекс строчки", JOptionPane.ERROR_MESSAGE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Data[][] newRowData = new Data[rowData.length + 1][rowData[0].length];
|
||||||
|
for (int row = 0; row < rowData.length + 1; row++) {
|
||||||
|
for (int col = 0; col < rowData[0].length; col++) {
|
||||||
|
if (row == i) {
|
||||||
|
newRowData[row][col] = new Data("", 0.);
|
||||||
|
} else if (row > i) {
|
||||||
|
newRowData[row][col] = rowData[row - 1][col];
|
||||||
|
} else {
|
||||||
|
newRowData[row][col] = rowData[row][col];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rowData = newRowData;
|
||||||
|
|
||||||
|
|
||||||
|
this.fireTableDataChanged();
|
||||||
|
this.fireTableStructureChanged();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeRow(int i)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getColumnNames() {
|
||||||
|
return columnNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColumnNames(String[] columnNames) {
|
||||||
|
this.columnNames = columnNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getColumnName(int column) {
|
||||||
|
return columnNames[column];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRowCount() {
|
||||||
|
return rowData.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColumnCount() {
|
||||||
|
return columnNames.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getValueAt(int row, int col) {
|
||||||
|
return rowData[row][col];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCellEditable(int row, int column) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValueAt(Object value, int row, int col) {
|
||||||
|
rowData[row][col] = new Data(value.toString());
|
||||||
|
fireTableCellUpdated(row, col);
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/LivadaPlan.java
Normal file
35
src/LivadaPlan.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
|
||||||
|
public class LivadaPlan extends JPanel {
|
||||||
|
|
||||||
|
private DataTableModel tableModel;
|
||||||
|
|
||||||
|
public LivadaPlan(Data[][] data) {
|
||||||
|
super(new BorderLayout());
|
||||||
|
|
||||||
|
String[] header = createHeader(data[0].length);
|
||||||
|
|
||||||
|
tableModel = new DataTableModel(data, header);
|
||||||
|
JTable table = new JTable(tableModel);
|
||||||
|
JScrollPane scrollPane = new JScrollPane(table);
|
||||||
|
|
||||||
|
JTable rowTable = new RowNumberTable(table);
|
||||||
|
scrollPane.setRowHeaderView(rowTable);
|
||||||
|
scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, rowTable.getTableHeader());
|
||||||
|
add(scrollPane, BorderLayout.CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataTableModel getTableModel() {
|
||||||
|
return tableModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] createHeader(int length) {
|
||||||
|
String[] header = new String[length];
|
||||||
|
for (int i = 1; i <= length; i++) {
|
||||||
|
header[i - 1] = i + "";
|
||||||
|
}
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/Main.java
Normal file
45
src/Main.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void createAndShowGUI() {
|
||||||
|
try {
|
||||||
|
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
|
||||||
|
} catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException |
|
||||||
|
IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create and set up the window.
|
||||||
|
JFrame frame = new JFrame("Livada");
|
||||||
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
|
||||||
|
DataReader dataReader = new DataReader();
|
||||||
|
|
||||||
|
String[][] trees = dataReader.readTrees("Derevia.in");
|
||||||
|
double[][] harvest = dataReader.readHarvest("Urojai.in", trees.length);
|
||||||
|
|
||||||
|
Data[][] data = dataReader.mergeData(trees, harvest);
|
||||||
|
|
||||||
|
//Create and set up the content pane.
|
||||||
|
LivadaPlan livadaPlan = new LivadaPlan(data);
|
||||||
|
livadaPlan.setOpaque(true);
|
||||||
|
frame.setContentPane(livadaPlan);
|
||||||
|
|
||||||
|
// Add menu bar with all 7 actions
|
||||||
|
frame.setJMenuBar(new MenuBar(livadaPlan.getTableModel()));
|
||||||
|
|
||||||
|
//Display the window.
|
||||||
|
frame.pack();
|
||||||
|
frame.setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
114
src/MenuBar.java
Normal file
114
src/MenuBar.java
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
|
public class MenuBar extends JMenuBar {
|
||||||
|
private DataTableModel tableModel;
|
||||||
|
|
||||||
|
public MenuBar(DataTableModel tableModel) {
|
||||||
|
this.tableModel = tableModel;
|
||||||
|
JMenu menu = new JMenu("Меню");
|
||||||
|
this.add(menu);
|
||||||
|
|
||||||
|
menu.add(createAddRowColItem());
|
||||||
|
menu.add(createRemoveRowColItem());
|
||||||
|
menu.add(createMockMenuItem("Макс Урожай"));
|
||||||
|
menu.add(createMockMenuItem("Средн Урожай"));
|
||||||
|
menu.add(createMockMenuItem("Общий урожай"));
|
||||||
|
menu.add(createMockMenuItem("Lin Spec"));
|
||||||
|
menu.add(createMockMenuItem("Сектор К деревьев"));
|
||||||
|
}
|
||||||
|
private JMenuItem createRemoveRowColItem() {
|
||||||
|
JMenuItem item = new JMenuItem();
|
||||||
|
item.setText("Удалить");
|
||||||
|
item.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
System.out.println("Remove Row/Col");
|
||||||
|
Object[] options = {"Удалить строку", "Удалить колонку", "Отмена"};
|
||||||
|
|
||||||
|
|
||||||
|
JPanel panel = new JPanel();
|
||||||
|
panel.add(new JLabel("Введите номер строки или стоблца который должен быть удален"));
|
||||||
|
JTextField textField = new JTextField(10);
|
||||||
|
panel.add(textField);
|
||||||
|
|
||||||
|
int result = JOptionPane.showOptionDialog(null,
|
||||||
|
panel, "Введите номер строки / столбца",
|
||||||
|
JOptionPane.YES_NO_CANCEL_OPTION,
|
||||||
|
JOptionPane.PLAIN_MESSAGE,
|
||||||
|
null,
|
||||||
|
options,
|
||||||
|
null);
|
||||||
|
if (textField.getText().trim().isEmpty()) {
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (result == JOptionPane.YES_OPTION) {
|
||||||
|
int row = Integer.parseInt(textField.getText());
|
||||||
|
System.out.println("Remove row # " + row);
|
||||||
|
tableModel.removeRow(row - 1);
|
||||||
|
} else if (result == JOptionPane.NO_OPTION) {
|
||||||
|
int column = Integer.parseInt(textField.getText());
|
||||||
|
System.out.println("Remove column # " + column);
|
||||||
|
// tableModel.removeColumn(column - 1);
|
||||||
|
} else {
|
||||||
|
System.out.println("Cancel add row/col");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}); return item;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private JMenuItem createMockMenuItem(String text) {
|
||||||
|
JMenuItem item = new JMenuItem(text);
|
||||||
|
item.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
JOptionPane.showMessageDialog(null, text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JMenuItem createAddRowColItem() {
|
||||||
|
JMenuItem item = new JMenuItem();
|
||||||
|
item.setText("Добавить");
|
||||||
|
item.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
System.out.println("Create Row/Col");
|
||||||
|
|
||||||
|
Object[] options = {"Добавить строку", "Добавить колонку", "Отмена"};
|
||||||
|
|
||||||
|
JPanel panel = new JPanel();
|
||||||
|
panel.add(new JLabel("Введите номер строки или стоблца который должен быть добавлен"));
|
||||||
|
JTextField textField = new JTextField(10);
|
||||||
|
panel.add(textField);
|
||||||
|
|
||||||
|
int result = JOptionPane.showOptionDialog(null,
|
||||||
|
panel, "Введите номер строки / столбца",
|
||||||
|
JOptionPane.YES_NO_CANCEL_OPTION,
|
||||||
|
JOptionPane.PLAIN_MESSAGE,
|
||||||
|
null,
|
||||||
|
options,
|
||||||
|
null);
|
||||||
|
if (textField.getText().trim().isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (result == JOptionPane.YES_OPTION) {
|
||||||
|
int row = Integer.parseInt(textField.getText());
|
||||||
|
System.out.println("Add row # " + row);
|
||||||
|
tableModel.addRow(row);
|
||||||
|
} else if (result == JOptionPane.NO_OPTION) {
|
||||||
|
int column = Integer.parseInt(textField.getText());
|
||||||
|
System.out.println("Add column # " + column);
|
||||||
|
tableModel.addColumn(column - 1);
|
||||||
|
} else {
|
||||||
|
System.out.println("Cancel add row/col");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
234
src/MenuDemo.java
Normal file
234
src/MenuDemo.java
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of Oracle or the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||||
|
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
/* MenuDemo.java requires images/middle.gif. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This class is just like MenuLookDemo, except the menu items
|
||||||
|
* actually do something, thanks to event listeners.
|
||||||
|
*/
|
||||||
|
public class MenuDemo implements ActionListener, ItemListener {
|
||||||
|
JTextArea output;
|
||||||
|
JScrollPane scrollPane;
|
||||||
|
String newline = "\n";
|
||||||
|
|
||||||
|
public JMenuBar createMenuBar() {
|
||||||
|
JMenuBar menuBar;
|
||||||
|
JMenu menu, submenu;
|
||||||
|
JMenuItem menuItem;
|
||||||
|
JRadioButtonMenuItem rbMenuItem;
|
||||||
|
JCheckBoxMenuItem cbMenuItem;
|
||||||
|
|
||||||
|
//Create the menu bar.
|
||||||
|
menuBar = new JMenuBar();
|
||||||
|
|
||||||
|
//Build the first menu.
|
||||||
|
menu = new JMenu("A Menu");
|
||||||
|
menu.setMnemonic(KeyEvent.VK_A);
|
||||||
|
menu.getAccessibleContext().setAccessibleDescription(
|
||||||
|
"The only menu in this program that has menu items");
|
||||||
|
menuBar.add(menu);
|
||||||
|
|
||||||
|
//a group of JMenuItems
|
||||||
|
menuItem = new JMenuItem("A text-only menu item",
|
||||||
|
KeyEvent.VK_T);
|
||||||
|
//menuItem.setMnemonic(KeyEvent.VK_T); //used constructor instead
|
||||||
|
menuItem.setAccelerator(KeyStroke.getKeyStroke(
|
||||||
|
KeyEvent.VK_1, ActionEvent.ALT_MASK));
|
||||||
|
menuItem.getAccessibleContext().setAccessibleDescription(
|
||||||
|
"This doesn't really do anything");
|
||||||
|
menuItem.addActionListener(this);
|
||||||
|
menu.add(menuItem);
|
||||||
|
|
||||||
|
ImageIcon icon = createImageIcon("images/middle.gif");
|
||||||
|
menuItem = new JMenuItem("Both text and icon", icon);
|
||||||
|
menuItem.setMnemonic(KeyEvent.VK_B);
|
||||||
|
menuItem.addActionListener(this);
|
||||||
|
menu.add(menuItem);
|
||||||
|
|
||||||
|
menuItem = new JMenuItem(icon);
|
||||||
|
menuItem.setMnemonic(KeyEvent.VK_D);
|
||||||
|
menuItem.addActionListener(this);
|
||||||
|
menu.add(menuItem);
|
||||||
|
|
||||||
|
//a group of radio button menu items
|
||||||
|
menu.addSeparator();
|
||||||
|
ButtonGroup group = new ButtonGroup();
|
||||||
|
|
||||||
|
rbMenuItem = new JRadioButtonMenuItem("A radio button menu item");
|
||||||
|
rbMenuItem.setSelected(true);
|
||||||
|
rbMenuItem.setMnemonic(KeyEvent.VK_R);
|
||||||
|
group.add(rbMenuItem);
|
||||||
|
rbMenuItem.addActionListener(this);
|
||||||
|
menu.add(rbMenuItem);
|
||||||
|
|
||||||
|
rbMenuItem = new JRadioButtonMenuItem("Another one");
|
||||||
|
rbMenuItem.setMnemonic(KeyEvent.VK_O);
|
||||||
|
group.add(rbMenuItem);
|
||||||
|
rbMenuItem.addActionListener(this);
|
||||||
|
menu.add(rbMenuItem);
|
||||||
|
|
||||||
|
//a group of check box menu items
|
||||||
|
menu.addSeparator();
|
||||||
|
cbMenuItem = new JCheckBoxMenuItem("A check box menu item");
|
||||||
|
cbMenuItem.setMnemonic(KeyEvent.VK_C);
|
||||||
|
cbMenuItem.addItemListener(this);
|
||||||
|
menu.add(cbMenuItem);
|
||||||
|
|
||||||
|
cbMenuItem = new JCheckBoxMenuItem("Another one");
|
||||||
|
cbMenuItem.setMnemonic(KeyEvent.VK_H);
|
||||||
|
cbMenuItem.addItemListener(this);
|
||||||
|
menu.add(cbMenuItem);
|
||||||
|
|
||||||
|
//a submenu
|
||||||
|
menu.addSeparator();
|
||||||
|
submenu = new JMenu("A submenu");
|
||||||
|
submenu.setMnemonic(KeyEvent.VK_S);
|
||||||
|
|
||||||
|
menuItem = new JMenuItem("An item in the submenu");
|
||||||
|
menuItem.setAccelerator(KeyStroke.getKeyStroke(
|
||||||
|
KeyEvent.VK_2, ActionEvent.ALT_MASK));
|
||||||
|
menuItem.addActionListener(this);
|
||||||
|
submenu.add(menuItem);
|
||||||
|
|
||||||
|
menuItem = new JMenuItem("Another item");
|
||||||
|
menuItem.addActionListener(this);
|
||||||
|
submenu.add(menuItem);
|
||||||
|
menu.add(submenu);
|
||||||
|
|
||||||
|
//Build second menu in the menu bar.
|
||||||
|
JMenuItem anotherMenu = new JMenuItem("Another Menu");
|
||||||
|
anotherMenu.setMnemonic(KeyEvent.VK_N);
|
||||||
|
anotherMenu.getAccessibleContext().setAccessibleDescription("This menu does nothing");
|
||||||
|
anotherMenu.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
System.out.println("Click!");
|
||||||
|
// JOptionPane.showMessageDialog(null, "Hello There!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menuBar.add(anotherMenu);
|
||||||
|
|
||||||
|
return menuBar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Container createContentPane() {
|
||||||
|
//Create the content-pane-to-be.
|
||||||
|
JPanel contentPane = new JPanel(new BorderLayout());
|
||||||
|
contentPane.setOpaque(true);
|
||||||
|
|
||||||
|
//Create a scrolled text area.
|
||||||
|
output = new JTextArea(5, 30);
|
||||||
|
output.setEditable(false);
|
||||||
|
scrollPane = new JScrollPane(output);
|
||||||
|
|
||||||
|
//Add the text area to the content pane.
|
||||||
|
contentPane.add(scrollPane, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
return contentPane;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
JMenuItem source = (JMenuItem)(e.getSource());
|
||||||
|
String s = "Action event detected."
|
||||||
|
+ newline
|
||||||
|
+ " Event source: " + source.getText()
|
||||||
|
+ " (an instance of " + getClassName(source) + ")";
|
||||||
|
output.append(s + newline);
|
||||||
|
output.setCaretPosition(output.getDocument().getLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void itemStateChanged(ItemEvent e) {
|
||||||
|
JMenuItem source = (JMenuItem)(e.getSource());
|
||||||
|
String s = "Item event detected."
|
||||||
|
+ newline
|
||||||
|
+ " Event source: " + source.getText()
|
||||||
|
+ " (an instance of " + getClassName(source) + ")"
|
||||||
|
+ newline
|
||||||
|
+ " New state: "
|
||||||
|
+ ((e.getStateChange() == ItemEvent.SELECTED) ?
|
||||||
|
"selected":"unselected");
|
||||||
|
output.append(s + newline);
|
||||||
|
output.setCaretPosition(output.getDocument().getLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns just the class name -- no package info.
|
||||||
|
protected String getClassName(Object o) {
|
||||||
|
String classString = o.getClass().getName();
|
||||||
|
int dotIndex = classString.lastIndexOf(".");
|
||||||
|
return classString.substring(dotIndex+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns an ImageIcon, or null if the path was invalid. */
|
||||||
|
protected static ImageIcon createImageIcon(String path) {
|
||||||
|
java.net.URL imgURL = MenuDemo.class.getResource(path);
|
||||||
|
if (imgURL != null) {
|
||||||
|
return new ImageIcon(imgURL);
|
||||||
|
} else {
|
||||||
|
System.err.println("Couldn't find file: " + path);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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("MenuDemo");
|
||||||
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
|
||||||
|
//Create and set up the content pane.
|
||||||
|
MenuDemo demo = new MenuDemo();
|
||||||
|
frame.setJMenuBar(demo.createMenuBar());
|
||||||
|
frame.setContentPane(demo.createContentPane());
|
||||||
|
|
||||||
|
//Display the window.
|
||||||
|
frame.setSize(450, 260);
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
167
src/RowNumberTable.java
Normal file
167
src/RowNumberTable.java
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.event.ChangeEvent;
|
||||||
|
import javax.swing.event.ChangeListener;
|
||||||
|
import javax.swing.event.TableModelEvent;
|
||||||
|
import javax.swing.event.TableModelListener;
|
||||||
|
import javax.swing.table.DefaultTableCellRenderer;
|
||||||
|
import javax.swing.table.JTableHeader;
|
||||||
|
import javax.swing.table.TableColumn;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This code is taken from - https://tips4java.wordpress.com/2008/11/18/row-number-table/
|
||||||
|
* Use a JTable as a renderer for row numbers of a given main table.
|
||||||
|
* This table must be added to the row header of the scrollpane that contains the main table.
|
||||||
|
*/
|
||||||
|
public class RowNumberTable extends JTable
|
||||||
|
implements ChangeListener, PropertyChangeListener, TableModelListener {
|
||||||
|
private JTable main;
|
||||||
|
|
||||||
|
public RowNumberTable(JTable table) {
|
||||||
|
main = table;
|
||||||
|
main.addPropertyChangeListener(this);
|
||||||
|
main.getModel().addTableModelListener(this);
|
||||||
|
|
||||||
|
setFocusable(false);
|
||||||
|
setAutoCreateColumnsFromModel(false);
|
||||||
|
setSelectionModel(main.getSelectionModel());
|
||||||
|
|
||||||
|
TableColumn column = new TableColumn();
|
||||||
|
column.setHeaderValue(" ");
|
||||||
|
addColumn(column);
|
||||||
|
column.setCellRenderer(new RowNumberRenderer());
|
||||||
|
|
||||||
|
getColumnModel().getColumn(0).setPreferredWidth(50);
|
||||||
|
setPreferredScrollableViewportSize(getPreferredSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addNotify() {
|
||||||
|
super.addNotify();
|
||||||
|
|
||||||
|
Component c = getParent();
|
||||||
|
|
||||||
|
// Keep scrolling of the row table in sync with the main table.
|
||||||
|
|
||||||
|
if (c instanceof JViewport) {
|
||||||
|
JViewport viewport = (JViewport) c;
|
||||||
|
viewport.addChangeListener(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delegate method to main table
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getRowCount() {
|
||||||
|
return main.getRowCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRowHeight(int row) {
|
||||||
|
int rowHeight = main.getRowHeight(row);
|
||||||
|
|
||||||
|
if (rowHeight != super.getRowHeight(row)) {
|
||||||
|
super.setRowHeight(row, rowHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rowHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No model is being used for this table so just use the row number
|
||||||
|
* as the value of the cell.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Object getValueAt(int row, int column) {
|
||||||
|
return Integer.toString(row + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't edit data in the main TableModel by mistake
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isCellEditable(int row, int column) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do nothing since the table ignores the model
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setValueAt(Object value, int row, int column) {
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implement the ChangeListener
|
||||||
|
//
|
||||||
|
public void stateChanged(ChangeEvent e) {
|
||||||
|
// Keep the scrolling of the row table in sync with main table
|
||||||
|
|
||||||
|
JViewport viewport = (JViewport) e.getSource();
|
||||||
|
JScrollPane scrollPane = (JScrollPane) viewport.getParent();
|
||||||
|
scrollPane.getVerticalScrollBar().setValue(viewport.getViewPosition().y);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implement the PropertyChangeListener
|
||||||
|
//
|
||||||
|
public void propertyChange(PropertyChangeEvent e) {
|
||||||
|
// Keep the row table in sync with the main table
|
||||||
|
|
||||||
|
if ("selectionModel".equals(e.getPropertyName())) {
|
||||||
|
setSelectionModel(main.getSelectionModel());
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("rowHeight".equals(e.getPropertyName())) {
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("model".equals(e.getPropertyName())) {
|
||||||
|
main.getModel().addTableModelListener(this);
|
||||||
|
revalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implement the TableModelListener
|
||||||
|
//
|
||||||
|
@Override
|
||||||
|
public void tableChanged(TableModelEvent e) {
|
||||||
|
revalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attempt to mimic the table header renderer
|
||||||
|
*/
|
||||||
|
private static class RowNumberRenderer extends DefaultTableCellRenderer {
|
||||||
|
public RowNumberRenderer() {
|
||||||
|
setHorizontalAlignment(JLabel.CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Component getTableCellRendererComponent(
|
||||||
|
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
||||||
|
if (table != null) {
|
||||||
|
JTableHeader header = table.getTableHeader();
|
||||||
|
|
||||||
|
if (header != null) {
|
||||||
|
setForeground(header.getForeground());
|
||||||
|
setBackground(header.getBackground());
|
||||||
|
setFont(header.getFont());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSelected) {
|
||||||
|
setFont(getFont().deriveFont(Font.BOLD));
|
||||||
|
}
|
||||||
|
|
||||||
|
setText((value == null) ? "" : value.toString());
|
||||||
|
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user