Re: Generate roof plugin
Hi Dorin, thank you, the grids are very well.
try this and SEND me privat the compiled plugin for test. The width of the edge panel we create with list width, not spaces.
package generateroof;
import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Event; import java.awt.GridBagConstraints; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.IOException; import java.net.URLEncoder; import java.util.HashSet; import java.util.ResourceBundle; import java.util.Set;
import javax.swing.AbstractAction; import javax.swing.AbstractButton; import javax.swing.ButtonGroup; import javax.swing.DefaultListCellRenderer; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JSlider; import javax.swing.JSpinner; import javax.swing.JTextField; import javax.swing.ListSelectionModel; import javax.swing.SpinnerNumberModel; import javax.swing.SwingUtilities; import javax.swing.border.TitledBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener;
import com.eteks.sweethome3d.model.HomeMaterial; import com.eteks.sweethome3d.model.UserPreferences; import com.eteks.sweethome3d.swing.AutoCommitSpinner; import com.eteks.sweethome3d.swing.ModelPreviewComponent; import com.eteks.sweethome3d.swing.NullableCheckBox; import com.eteks.sweethome3d.swing.NullableSpinner; import com.eteks.sweethome3d.swing.SwingTools; import com.eteks.sweethome3d.swing.NullableSpinner.NullableSpinnerLengthModel; import com.eteks.sweethome3d.tools.OperatingSystem; import com.eteks.sweethome3d.viewcontroller.HomeView;
public class GenrateRoofPluginView { private final GenerateRoofPlugin plugin;
public GenrateRoofPluginView(GenerateRoofPlugin generateRoofPlugin) { this.plugin = generateRoofPlugin; }
float resolutionScale = SwingTools.getResolutionScale(); ModelPreviewComponent roofPreview; ChangeListener commonListener; ListSelectionListener edgesListener; NullableCheckBox invisibilityCheck, showHome, showTexture, reverseFaces; JSlider faceAngleSlider; JRadioButton verticalBorder, orthoBorder; ImageIcon vertIcon, vertSelIcon, orthoIcon, orthoSelIcon; ButtonGroup borderGroupBtn; JButton resetButton, aboutButton; NullableSpinnerLengthModel thickModel, roofElevationModel; NullableSpinner thick, roofElevation; JSpinner fineSlope; JList<SlopedEdge> edgesList; JScrollPane scrollEdgesPane; JTextField creator; JLabel edgesLabel, invisibilityLabel; JPanel invisibilityPane, slopePane, bordersPane, finePane, thickPane, elevationPane, creatorPane;
/** * Creates and layout the components shown in the dialog box of this plug-in. * * @author Daniels118 * * @param homeView * @param resource */ protected void createComponents(final HomeView homeView, final ResourceBundle resource) { UserPreferences preferences = plugin.getUserPreferences(); String unitName = preferences.getLengthUnit().getName();
// Create a common change listener for some components. commonListener = new ChangeListener() { @Override public void stateChanged(ChangeEvent ev) { if (ev.getSource().equals(showHome)) { if (showHome.getValue()) { plugin.homeItems.removeAllChildren(); plugin.homeItems = plugin.createHomeNode(plugin.getHome()); } plugin.refreshRoof(homeView, resource);
} else if (ev.getSource().equals(faceAngleSlider)) { int slope = faceAngleSlider.getValue(); int maxAngle = faceAngleSlider.getMaximum() - 1; // Limit the slope in range 1 to 179 degrees slope = slope > 1 ? slope : 1; slope = slope < maxAngle ? slope : maxAngle; // Update the angle for the selected faces for (SlopedEdge edge : edgesList.getSelectedValuesList()) edge.setSlope(slope); fineSlope.removeChangeListener(commonListener); fineSlope.setValue(0.0); fineSlope.addChangeListener(commonListener); if (!faceAngleSlider.getValueIsAdjusting() && faceAngleSlider.hasFocus()) { edgesList.updateUI(); plugin.updateSelectedFacesFromList(homeView, resource); } } else if (ev.getSource().equals(fineSlope)) { // Add the fine tuning to edge slope float fineSlopeVal = ((Number) fineSlope.getValue()).floatValue(); float angle = faceAngleSlider.getValue(); float maxAngle = faceAngleSlider.getMaximum() - 1; float slope = angle + fineSlopeVal; slope = slope > 1f ? slope : 1.0f; slope = slope < maxAngle ? slope : maxAngle; // Update the angle for the selected faces for (SlopedEdge edge : edgesList.getSelectedValuesList()) edge.setSlope(slope); edgesList.updateUI(); plugin.updateSelectedFacesFromList(homeView, resource); } else if (ev.getSource().equals(invisibilityCheck)) { if (invisibilityCheck.getValue() != null) { boolean visible = !invisibilityCheck.getValue(); // Update the face visibility for (SlopedEdge edge : edgesList.getSelectedValuesList()) edge.setFaceVisible(visible); edgesList.updateUI(); plugin.updateSelectedFacesFromList(homeView, resource); } } else { plugin.refreshRoof(homeView, resource); } } };
// Create edges list selection listener. edgesListener = new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent ev) { int edgeSelection = edgesList.getSelectedIndices().length; // Limit selection to have at least one face with slope < 90 deg int maxAngle = edgeSelection < plugin.allRoofEdges.length ? 180 : 76; if (faceAngleSlider.getMaximum() != maxAngle) faceAngleSlider.setMaximum(maxAngle); SlopedEdge edge = edgesList.getSelectedValue(); if (edge != null) { // Set angle faceAngleSlider.removeChangeListener(commonListener); faceAngleSlider.setValue((int) edge.getSlope()); faceAngleSlider.addChangeListener(commonListener); // Set fine slope fineSlope.removeChangeListener(commonListener); fineSlope.setValue(edge.getSlope() - faceAngleSlider.getValue()); fineSlope.addChangeListener(commonListener); } if (!ev.getValueIsAdjusting() && edgesList.hasFocus()) plugin.updateSelectedFacesFromList(homeView, resource); } }; // Create preview roofPreview = new ModelPreviewComponent(true, true, true, true); roofPreview.setFocusable(false); roofPreview.setPreferredSize(new Dimension((int) (800 * resolutionScale), (int) (600 * resolutionScale)));// @byDMA resizing window to 800x600 // Add a mouse listener to get selected faces roofPreview.addMouseListener(new MouseAdapter() { private Set<SlopedEdge> selectedEdges = new HashSet<SlopedEdge>();// Using a set avoids duplicates
@Override public void mouseClicked(MouseEvent ev) { HomeMaterial pickedMaterial = roofPreview.getPickedMaterial(); boolean sInterval = false; if (pickedMaterial != null) { String faceName = pickedMaterial.getName(); for (RoofFace face : plugin.faces) { if (faceName.equals(face.getFaceName())) { if ((ev.getModifiers() & Event.CTRL_MASK) != 0 || (ev.getModifiers() & Event.SHIFT_MASK) != 0) { for (SlopedEdge sEdge : face.getGeneratingEdges()) { if (!selectedEdges.add(sEdge)) selectedEdges.remove(sEdge);// Toggle selection } if ((ev.getModifiers() & Event.SHIFT_MASK) != 0) sInterval = true; } else { selectedEdges.clear(); for (SlopedEdge sEdge : face.getGeneratingEdges()) selectedEdges.add(sEdge); } break;// There can be a single face matching the picked material } } int[] edgeIndices = new int[selectedEdges.size()]; int i = 0; for (SlopedEdge sEdge : selectedEdges) edgeIndices[i++] = sEdge.getEdge(); edgesList.setSelectedIndices(edgeIndices); int sMin = edgesList.getMinSelectionIndex(); int sMax = edgesList.getMaxSelectionIndex(); if (sInterval) edgesList.addSelectionInterval(sMin, sMax); if (i > 0) edgesList.ensureIndexIsVisible(edgeIndices[i - 1]); } else if ((ev.getModifiers() & Event.CTRL_MASK) == 0) { edgesList.setSelectedIndices(new int[0]);// Deselect when click the background } edgesList.updateUI(); plugin.updateSelectedFacesFromList(homeView, resource); } });
// Create edges list // String edgesLabel = resource.getString("edges.txt");// Edges: Slope edgesList = new JList<SlopedEdge>(); edgesList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); edgesList.setListData(plugin.allRoofEdges);// Add edges to the list edgesList.setCellRenderer(new EdgesCellRenderer()); edgesList.addListSelectionListener(edgesListener); edgesList.setFixedCellWidth(140);// byDMA resize width of the List in the JScrollPane // Put edges list into scroll panel String edgesLab = resource.getString("edges.txt");// Edges: Slope edgesLabel = new JLabel(edgesLab);// Edges: Slope // scrollEdges = SwingTools.createScrollPane(edgesList); scrollEdgesPane = new JScrollPane(edgesList); if (OperatingSystem.isMacOSX()) { Dimension preferredSize = scrollEdgesPane.getPreferredSize(); scrollEdgesPane.setPreferredSize(new Dimension(Math.min(200, preferredSize.width), preferredSize.height)); } else { scrollEdgesPane.setBorder(new TitledBorder(edgesLabel.getText())); }
// Create slope slider String slopeSliderLabel = resource.getString("slope.txt");// Slope faceAngleSlider = new JSlider(JSlider.VERTICAL, 0, 180, 40); faceAngleSlider.setPaintTicks(true); faceAngleSlider.setPaintLabels(true); faceAngleSlider.setMajorTickSpacing(30); faceAngleSlider.setMinorTickSpacing(5); faceAngleSlider.setBorder(new TitledBorder(slopeSliderLabel)); faceAngleSlider.addChangeListener(commonListener);
// Create fine slope angle spinner SpinnerNumberModel fineSlopeModel = new SpinnerNumberModel(.0, -0.9, 0.9, .1); fineSlope = new AutoCommitSpinner(fineSlopeModel); fineSlope.addChangeListener(commonListener); // Fine angle panel String fineSlopeShort = resource.getString("fineSlope.txt");// Fine slope finePane = SwingTools.createTitledPanel(fineSlopeShort); finePane.add(fineSlope);
// Create face invisibility check box String invisibility = resource.getString("invisibility.txt");// Invisible invisibilityCheck = new NullableCheckBox(invisibility); invisibilityCheck.setNullable(false); invisibilityCheck.setValue(false); invisibilityCheck.addChangeListener(commonListener); // Invisibility check panel String faceVisible = resource.getString("face.txt");// Face invisibilityLabel = new JLabel(faceVisible); if (OperatingSystem.isMacOSX()) { invisibilityPane = SwingTools.createTitledPanel(null); } else { invisibilityPane = SwingTools.createTitledPanel(invisibilityLabel.getText()); } invisibilityPane.add(invisibilityCheck);
// Create roof border thickness spinner String thickLong = String.format(resource.getString("thickness.txt"), unitName);// Roof thickness thickModel = new NullableSpinnerLengthModel(preferences, 7.6f, 2.5f, 30.5f); thick = new NullableSpinner(thickModel); thick.setToolTipText(thickLong); // Thickness panel String thickShort = String.format(resource.getString("thick.txt"), unitName);// Thick thickPane = SwingTools.createTitledPanel(thickShort); thickPane.add(thick); if (plugin.isRoofSelected()) { String sThickness = plugin.currentRoof.getProperty(GenerateRoofPlugin.ROOF_THICKNESS); if (sThickness != null) { float currentThick = Float.valueOf(sThickness); try { thickModel.setLength(currentThick); } catch (Exception e) { /** * @author Daniels118 No need to translate this message, only "hackers" have * chances to see it */ plugin.getHomeController().getView().showError("Cannot retrieve thickModel: " + e.getMessage()); } } } thickModel.addChangeListener(commonListener);
// Create roof elevation spinner String elevationLong = String.format(resource.getString("roofelevation.txt"), unitName);// Elevate roof at needed position roofElevationModel = new NullableSpinnerLengthModel(preferences, 0.0f, 0.0f, 9999f); roofElevation = new NullableSpinner(roofElevationModel); roofElevation.setToolTipText(elevationLong); roofElevationModel.setLength(plugin.getRoofElevation(plugin.currentLevel)); roofElevationModel.addChangeListener(commonListener); // Elevation panel String elevationShort = String.format(resource.getString("elevation.txt"), unitName);// Elevation(%s) elevationPane = SwingTools.createTitledPanel(elevationShort); elevationPane.add(roofElevation);
// Create home visibility check box String displayHome = resource.getString("displayHomeCheckBox.txt");// Show home showHome = new NullableCheckBox(displayHome); showHome.setValue(false); showHome.addChangeListener(commonListener);
// Create texture visibility check box String useTexture = resource.getString("displayTextureCheckBox.txt");// Use roof texture showTexture = new NullableCheckBox(useTexture); showTexture.setValue(false); showTexture.setEnabled(plugin.isRoofSelected()); showTexture.addChangeListener(commonListener);
// Create reverse faces check box String reverseFacesTxt = resource.getString("reverseFaces.txt");// Reverse faces reverseFaces = new NullableCheckBox(reverseFacesTxt); reverseFaces.setValue(false); reverseFaces.addChangeListener(commonListener);
// Create creator field String author = System.getProperty("user.name"); if (plugin.isRoofSelected()) author = plugin.currentRoof.getCreator(); creator = new JTextField(author); creator.setEditable(true); // @byDMA 2. store default height for TextField creator int defaultHeight = creator.getSize().getHeight(); // @byDMA 3. set custom width and default height creator.setSize(new Dimension(250, defaultHeight));
// Creator panel String authorText = resource.getString("authorText.txt");// Creator creatorPane = SwingTools.createTitledPanel(authorText); creatorPane.add(creator);
// Create borders radio buttons vertIcon = new ImageIcon(GenerateRoofPlugin.class.getResource("/generateroof/resources/vert.png")); vertSelIcon = new ImageIcon(GenerateRoofPlugin.class.getResource("/generateroof/resources/vertSel.png")); orthoIcon = new ImageIcon(GenerateRoofPlugin.class.getResource("/generateroof/resources/ortho.png")); orthoSelIcon = new ImageIcon(GenerateRoofPlugin.class.getResource("/generateroof/resources/orthoSel.png")); // Vertical border button verticalBorder = new JRadioButton(vertIcon, true);// default selected verticalBorder.setActionCommand("vertical"); verticalBorder.setSelectedIcon(vertSelIcon); // Orthogonal border button orthoBorder = new JRadioButton(orthoIcon); orthoBorder.setActionCommand("orthoUp"); orthoBorder.setSelectedIcon(orthoSelIcon); // Group border direction buttons borderGroupBtn = new ButtonGroup(); borderGroupBtn.add(verticalBorder); borderGroupBtn.add(orthoBorder); // Border orientation panel String borders = resource.getString("borderText.txt");// Border bordersPane = SwingTools.createTitledPanel(borders); bordersPane.add(verticalBorder, 0); bordersPane.add(orthoBorder, 1); // Set initial border if (plugin.isRoofSelected()) { String dirThick = plugin.getSelectedRoof().getProperty(GenerateRoofPlugin.ROOF_THICKNESS_DIRECTION); if (dirThick != null) { try { if (orthoBorder.getActionCommand().equals(dirThick)) borderGroupBtn.setSelected(orthoBorder.getModel(), true); } catch (Exception e) { /** * @author Daniels118 No need to translate this message, only "hackers" have * chances to see it */ plugin.getHomeController().getView().showError("Cannot retrieve direction: " + e.getMessage()); } } } // Create a listener for the border buttons. ActionListener borderActionListener = new ActionListener() { public void actionPerformed(ActionEvent actionEvent) { AbstractButton aButton = (AbstractButton) actionEvent.getSource(); if (aButton.isSelected()) plugin.refreshRoof(homeView, resource); } }; // Register a listener for the borders buttons. verticalBorder.addActionListener(borderActionListener); orthoBorder.addActionListener(borderActionListener);
// Create reset button resetButton = new JButton(new AbstractAction(resource.getString("resetButton.txt")) { private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent ev) { faceAngleSlider.setValue(40); fineSlope.setValue(0.0); thickModel.setLength(7.6f); edgesList.setSelectedIndices(new int[0]); invisibilityCheck.setNullable(false); invisibilityCheck.setValue(false); invisibilityCheck.setValue(false); // Reset the angle for all faces to 40 deg int slope = faceAngleSlider.getValue(); for (int i = 0; i < plugin.allRoofEdges.length; i++) { plugin.allRoofEdges.setSlope(slope); plugin.allRoofEdges.setFaceVisible(true); } // Reset the author String author = System.getProperty("user.name"); creator.setText(author); // Reset the borders borderGroupBtn.setSelected(verticalBorder.getModel(), true); edgesList.updateUI(); plugin.updateSelectedFacesFromList(homeView, resource); } }); resetButton.setToolTipText(resource.getString("resetButtonInf.txt"));
// About button aboutButton = new JButton(new AbstractAction(resource.getString("aboutButton.txt")) { private static final long serialVersionUID = 1L;
@Override public void actionPerformed(ActionEvent ev) { HTMLViewer viewer = new HTMLViewer(); viewer.addErrorListener(new HTMLViewer.ErrorListener() { @Override public void onError(Exception e) { e.printStackTrace(); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { viewer.setPage(GenerateRoofPlugin.class.getResource("/generateroof/resources/about.html")); } catch (IOException e1) { e1.printStackTrace(); } } }); } }); try { String lang = resource.getLocale().getLanguage(); String version = plugin.getVersion(); String url = "https://daniels118.altervista.org/sh3d/roofgenerator/about/" + "?lang=" + lang + "&ver=" + URLEncoder.encode(version, "UTF8"); viewer.setPage(url); } catch (IOException e) { e.printStackTrace(); } JScrollPane scrollPane = new JScrollPane(viewer); JOptionPane helpPanel = new JOptionPane(scrollPane, JOptionPane.PLAIN_MESSAGE, JOptionPane.DEFAULT_OPTION); JDialog aboutDialog = helpPanel.createDialog((JComponent) homeView, resource.getString("ROOF_GEN.title")); aboutDialog.applyComponentOrientation(((JComponent) homeView).getComponentOrientation()); aboutDialog.setLocationByPlatform(true); aboutDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); aboutDialog.setResizable(true); aboutDialog.setMinimumSize(new Dimension(600, 700)); aboutDialog.setVisible(true); } }); //aboutButton.setBackground(Color.green); //standard button, not green aboutButton.setToolTipText(resource.getString("aboutButton_Warn.txt")); }
/** * Layout user interface * @author Daniels118 & byDMA */ protected JPanel createUI() { JPanel roofPanel = SwingTools.createTitledPanel(null); roofPanel.setBorder(null); // Column 0~3 Row 0~9 roofPanel.add(roofPreview, new GridBagConstraints(0, 0, 4, 9, 1, 1, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); // Column 4 Row 1 if (OperatingSystem.isMacOSX()) { roofPanel.add(edgesLabel, new GridBagConstraints(4, 0, 2, 1, 0, 0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(0, 10, 0, 0), 0, 0)); } // Column 4+5 Row 0~7 roofPanel.add(scrollEdgesPane, new GridBagConstraints(4, 0, 2, 7, 0, 0, GridBagConstraints.NORTH, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); // Column 4+5 Row 9 roofPanel.add(resetButton, new GridBagConstraints(4, 9, 2, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); if (OperatingSystem.isMacOSX()) { roofPanel.add(invisibilityLabel, new GridBagConstraints(5, 1, 1, 1, 0, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(0, 10, 0, 0), 0, 0)); } // Column 6+7 Row 0 roofPanel.add(invisibilityPane, new GridBagConstraints(6, 0, 2, 1, 0, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); // Column 6+7 Row 1~5 roofPanel.add(faceAngleSlider, new GridBagConstraints(6, 1, 2, 5, 0, 1, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); // Column 6+7 Row 6 roofPanel.add(finePane, new GridBagConstraints(6, 6, 2, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); // Column 4+5 Row 7 roofPanel.add(thickPane, new GridBagConstraints(4, 7, 2, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); // Column 6+7 Row 7 roofPanel.add(elevationPane, new GridBagConstraints(6, 7, 2, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); // Column 6+7 Row 8 roofPanel.add(creatorPane, new GridBagConstraints(6, 8, 2, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); // Column 0 Row 9 roofPanel.add(showHome, new GridBagConstraints(0, 9, 1, 1, 1, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); // Column 2 Row 9 roofPanel.add(showTexture, new GridBagConstraints(2, 9, 1, 1, 0, 0, GridBagConstraints.LINE_END, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); // Column 3 Row 9 roofPanel.add(reverseFaces, new GridBagConstraints(3, 9, 1, 1, 0, 0, GridBagConstraints.LINE_END, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); // Column 4+5 Row 8 roofPanel.add(bordersPane, new GridBagConstraints(4, 8, 2, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); // Column 6+7 Row 9 roofPanel.add(aboutButton, new GridBagConstraints(6, 9, 2, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); // First refresh roof edgesList.updateUI(); plugin.refreshRoof(plugin.homeView, plugin.resource); return roofPanel; }
private class EdgesCellRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = 1L; final ImageIcon eyeCloseIcon = new ImageIcon(GenerateRoofPlugin.class.getResource("/generateroof/resources/closed-eye.png")); final ImageIcon emptyIcon = new ImageIcon(GenerateRoofPlugin.class.getResource("/generateroof/resources/emptyIcon.png"));
@Override public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) { String s = value.toString(); setText(s); boolean visible = plugin.allRoofEdges[index].isFaceVisible(); setIcon(!visible ? eyeCloseIcon : emptyIcon);
if (isSelected) { setBackground(list.getSelectionBackground()); setForeground(list.getSelectionForeground()); } else { setBackground(list.getBackground()); setForeground(list.getForeground()); }
setEnabled(list.isEnabled()); setFont(list.getFont()); setOpaque(true); return this; }
}
}
|