mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
common controls extracted to the platform + messages moved to the right bundle
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.util.ui;
|
||||
|
||||
import com.intellij.openapi.fileChooser.FileChooser;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ui.AbstractTableCellEditor;
|
||||
import com.intellij.util.ui.CellEditorComponentWithBrowseButton;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
public class LocalPathCellEditor extends AbstractTableCellEditor {
|
||||
private final String myTitle;
|
||||
|
||||
private CellEditorComponentWithBrowseButton<JTextField> myComponent;
|
||||
|
||||
public LocalPathCellEditor(String title) {
|
||||
myTitle = title;
|
||||
}
|
||||
|
||||
public Object getCellEditorValue() {
|
||||
return myComponent.getChildComponent().getText();
|
||||
}
|
||||
|
||||
public Component getTableCellEditorComponent(final JTable table, Object value, boolean isSelected, final int row, int column) {
|
||||
ActionListener listener = new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
FileChooserDescriptor d = new FileChooserDescriptor(false, true, false, true, false, false);
|
||||
if (myTitle != null) {
|
||||
d.setTitle(myTitle);
|
||||
}
|
||||
d.setShowFileSystemRoots(true);
|
||||
|
||||
VirtualFile initialFile = LocalFileSystem.getInstance().findFileByPath((String)getCellEditorValue());
|
||||
VirtualFile[] files = FileChooser.chooseFiles(table, d, initialFile);
|
||||
if (files.length == 1 && files[0] != null) {
|
||||
String path = files[0].getPresentableUrl();
|
||||
if (SystemInfo.isWindows && path.length() == 2 && Character.isLetter(path.charAt(0)) && path.charAt(1) == ':') {
|
||||
path += "\\"; // make path absolute
|
||||
}
|
||||
myComponent.getChildComponent().setText(path);
|
||||
}
|
||||
}
|
||||
};
|
||||
myComponent = new CellEditorComponentWithBrowseButton<JTextField>(new TextFieldWithBrowseButton(listener), this);
|
||||
myComponent.getChildComponent().setText((String)value);
|
||||
return myComponent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.util.ui.ValidatingTableEditor">
|
||||
<grid id="27dc6" binding="myContentPane" layout-manager="GridLayoutManager" row-count="4" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="400"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<scrollpane id="11f79">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="3" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="37d9d" class="com.intellij.ui.table.TableView" binding="myTable" custom-create="true">
|
||||
<constraints/>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</scrollpane>
|
||||
<component id="38e47" class="javax.swing.JButton" binding="myAddButton" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="A&dd"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="79576" class="javax.swing.JButton" binding="myRemoveButton" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="&Remove"/>
|
||||
</properties>
|
||||
</component>
|
||||
<hspacer id="ef5dc">
|
||||
<constraints>
|
||||
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
<grid id="a830f" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="b1d0" class="javax.swing.JLabel" binding="myMessageLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Label"/>
|
||||
</properties>
|
||||
</component>
|
||||
<hspacer id="a0645">
|
||||
<constraints>
|
||||
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
<component id="4d864" class="com.intellij.ui.HoverHyperlinkLabel" binding="myFixLink" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Fix"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<vspacer id="4ae4a">
|
||||
<constraints>
|
||||
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
@@ -0,0 +1,337 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.util.ui;
|
||||
|
||||
import com.intellij.openapi.util.NullableComputable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.ui.HoverHyperlinkLabel;
|
||||
import com.intellij.ui.table.TableView;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.JTableHeader;
|
||||
import javax.swing.table.TableCellEditor;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class ValidatingTableEditor<Item> {
|
||||
|
||||
private static final Icon WARNING_ICON = UIUtil.getBalloonWarningIcon();
|
||||
private static final Icon EMPTY_ICON = new EmptyIcon(WARNING_ICON);
|
||||
private static final String REMOVE_KEY = "REMOVE_SELECTED";
|
||||
|
||||
public interface RowHeightProvider {
|
||||
int getRowHeight();
|
||||
}
|
||||
|
||||
public interface Fix extends Runnable {
|
||||
String getTitle();
|
||||
}
|
||||
|
||||
private class ColumnInfoWrapper extends ColumnInfo<Item, String> {
|
||||
private final ColumnInfo<Item, String> myDelegate;
|
||||
|
||||
public ColumnInfoWrapper(ColumnInfo<Item, String> delegate) {
|
||||
super(delegate.getName());
|
||||
myDelegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String valueOf(Item item) {
|
||||
return myDelegate.valueOf(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(Item item) {
|
||||
return myDelegate.isCellEditable(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(Item item, String value) {
|
||||
myDelegate.setValue(item, value);
|
||||
updateMessage(-1, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableCellEditor getEditor(Item item) {
|
||||
return myDelegate.getEditor(item);
|
||||
}
|
||||
}
|
||||
|
||||
private JPanel myContentPane;
|
||||
private TableView<Item> myTable;
|
||||
private JButton myAddButton;
|
||||
private JButton myRemoveButton;
|
||||
private JLabel myMessageLabel;
|
||||
private HoverHyperlinkLabel myFixLink;
|
||||
private final List<String> myWarnings = new ArrayList<String>();
|
||||
private Fix myFixRunnable;
|
||||
|
||||
protected abstract Item cloneOf(Item item);
|
||||
|
||||
@Nullable
|
||||
protected abstract Pair<String, Fix> validate(List<Item> current, List<String> warnings);
|
||||
|
||||
protected abstract Item createItem();
|
||||
|
||||
private class IconColumn extends ColumnInfo<Item, Object> implements RowHeightProvider {
|
||||
public IconColumn() {
|
||||
super(" ");
|
||||
}
|
||||
|
||||
public String valueOf(Item item) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth(JTable table) {
|
||||
return WARNING_ICON.getIconWidth() + 2;
|
||||
}
|
||||
|
||||
public int getRowHeight() {
|
||||
return WARNING_ICON.getIconHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableCellRenderer getRenderer(final Item item) {
|
||||
return new WarningIconCellRenderer(new NullableComputable<String>() {
|
||||
public String compute() {
|
||||
return myWarnings.get(doGetItems().indexOf(item));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void createUIComponents() {
|
||||
myTable = new ChangesTrackingTableView<Item>() {
|
||||
protected void onTextChanged(int row, int column, String value) {
|
||||
final Item original = getItems().get(row);
|
||||
Item override = cloneOf(original);
|
||||
final ColumnInfo<Item, String> columnInfo = getTableModel().getColumnInfos()[column];
|
||||
columnInfo.setValue(override, value);
|
||||
updateMessage(row, override);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEditingStopped() {
|
||||
updateMessage(-1, null);
|
||||
}
|
||||
};
|
||||
|
||||
myFixLink = new HoverHyperlinkLabel(null);
|
||||
}
|
||||
|
||||
protected ValidatingTableEditor() {
|
||||
myTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
updateButtons();
|
||||
}
|
||||
});
|
||||
|
||||
myTable.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), REMOVE_KEY);
|
||||
myTable.getActionMap().put(REMOVE_KEY, new AbstractAction() {
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
removeSelected();
|
||||
}
|
||||
});
|
||||
|
||||
myFixLink.addHyperlinkListener(new HyperlinkListener() {
|
||||
public void hyperlinkUpdate(HyperlinkEvent e) {
|
||||
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED && myFixRunnable != null) {
|
||||
myFixRunnable.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
myAddButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
addItem();
|
||||
}
|
||||
});
|
||||
|
||||
myRemoveButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
removeSelected();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void removeSelected() {
|
||||
myTable.stopEditing();
|
||||
List<Item> items = new ArrayList<Item>(doGetItems());
|
||||
final int[] rows = myTable.getSelectedRows();
|
||||
for (int i = rows.length - 1; i >= 0; i--) {
|
||||
items.remove(rows[i]);
|
||||
}
|
||||
|
||||
setItems(items);
|
||||
updateMessage(-1, null);
|
||||
|
||||
if (!items.isEmpty()) {
|
||||
int index = Math.min(rows[0], items.size() - 1);
|
||||
myTable.getSelectionModel().addSelectionInterval(index, index);
|
||||
}
|
||||
}
|
||||
|
||||
protected void addItem() {
|
||||
List<Item> items = new ArrayList<Item>(doGetItems());
|
||||
items.add(createItem());
|
||||
|
||||
setItems(items);
|
||||
|
||||
final int row = items.size() - 1;
|
||||
myTable.getSelectionModel().setSelectionInterval(row, row);
|
||||
myTable.scrollRectToVisible(myTable.getCellRect(row, 0, true));
|
||||
if (getTableModel().getColumnInfos()[1].isCellEditable(items.get(row))) {
|
||||
myTable.editCellAt(row, 1);
|
||||
IdeFocusManager.findInstanceByComponent(myContentPane).requestFocus(myTable.getEditorComponent(), true);
|
||||
}
|
||||
updateMessage(-1, null);
|
||||
}
|
||||
|
||||
private ListTableModel<Item> getTableModel() {
|
||||
return (ListTableModel<Item>)myTable.getModel();
|
||||
}
|
||||
|
||||
public void setModel(ColumnInfo<Item, String>[] valueColumns, List<Item> items) {
|
||||
ColumnInfo[] columns = new ColumnInfo[valueColumns.length + 1];
|
||||
IconColumn iconColumn = new IconColumn();
|
||||
int maxHeight = iconColumn.getRowHeight();
|
||||
|
||||
columns[0] = iconColumn;
|
||||
for (int i = 0; i < valueColumns.length; i++) {
|
||||
columns[i + 1] = new ColumnInfoWrapper(valueColumns[i]);
|
||||
if (valueColumns[i] instanceof RowHeightProvider) {
|
||||
maxHeight = Math.max(maxHeight, ((RowHeightProvider)valueColumns[i]).getRowHeight());
|
||||
}
|
||||
}
|
||||
|
||||
myTable.stopEditing();
|
||||
myTable.setModel(new ListTableModel<Item>(columns));
|
||||
if (maxHeight > 0) {
|
||||
myTable.setRowHeight(maxHeight);
|
||||
}
|
||||
|
||||
setItems(items);
|
||||
updateMessage(-1, null);
|
||||
}
|
||||
|
||||
public List<Item> getItems() {
|
||||
return Collections.unmodifiableList(doGetItems());
|
||||
}
|
||||
|
||||
private List<Item> doGetItems() {
|
||||
List<Item> items = new ArrayList<Item>(getTableModel().getItems());
|
||||
if (myTable.isEditing()) {
|
||||
Component c = myTable.getEditorComponent();
|
||||
final JTextField textField;
|
||||
if (c instanceof CellEditorComponentWithBrowseButton) {
|
||||
textField = (JTextField)((CellEditorComponentWithBrowseButton)c).getChildComponent();
|
||||
}
|
||||
else {
|
||||
textField = (JTextField)c;
|
||||
}
|
||||
String value = textField.getText();
|
||||
ColumnInfo column = ((ListTableModel)myTable.getModel()).getColumnInfos()[myTable.getEditingColumn()];
|
||||
((ColumnInfoWrapper)column).myDelegate.setValue(items.get(myTable.getEditingRow()), value);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
private void setItems(List<Item> items) {
|
||||
if (items.isEmpty()) {
|
||||
getTableModel().setItems(Collections.<Item>emptyList());
|
||||
myWarnings.clear();
|
||||
}
|
||||
else {
|
||||
getTableModel().setItems(new ArrayList<Item>(items));
|
||||
for (Item item : items) {
|
||||
myWarnings.add(null);
|
||||
}
|
||||
}
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
public void setTableHeader(JTableHeader header) {
|
||||
myTable.setTableHeader(header);
|
||||
}
|
||||
|
||||
private void updateButtons() {
|
||||
myRemoveButton.setEnabled(myTable.getSelectedRow() != -1);
|
||||
}
|
||||
|
||||
public void updateMessage(int index, @Nullable Item override) {
|
||||
List<Item> current = new ArrayList<Item>(doGetItems());
|
||||
if (override != null) {
|
||||
current.set(index, override);
|
||||
}
|
||||
|
||||
Pair<String, Fix> messageAndFix = validate(current, myWarnings);
|
||||
if (messageAndFix != null) {
|
||||
myMessageLabel.setText(messageAndFix.first);
|
||||
myMessageLabel.setIcon(WARNING_ICON);
|
||||
myMessageLabel.setVisible(true);
|
||||
myFixRunnable = messageAndFix.second;
|
||||
myFixLink.setVisible(myFixRunnable != null);
|
||||
myFixLink.setText(myFixRunnable != null ? myFixRunnable.getTitle() : null);
|
||||
}
|
||||
else {
|
||||
myMessageLabel.setText(" ");
|
||||
myMessageLabel.setIcon(EMPTY_ICON);
|
||||
myFixLink.setVisible(false);
|
||||
myFixRunnable = null;
|
||||
}
|
||||
myTable.repaint();
|
||||
}
|
||||
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myTable;
|
||||
}
|
||||
|
||||
|
||||
private static class WarningIconCellRenderer extends DefaultTableCellRenderer {
|
||||
private final NullableComputable<String> myWarningProvider;
|
||||
|
||||
public WarningIconCellRenderer(NullableComputable<String> warningProvider) {
|
||||
myWarningProvider = warningProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
||||
JLabel label = (JLabel)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||
String message = myWarningProvider.compute();
|
||||
label.setIcon(message != null ? WARNING_ICON : null);
|
||||
label.setToolTipText(message);
|
||||
label.setHorizontalAlignment(CENTER);
|
||||
label.setVerticalAlignment(CENTER);
|
||||
return label;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user