0

我有一个 JPanel,其中有可移动的组件。

我的问题是,如果我在面板中使用一个动作,则整个面板中组件的位置将它们的位置更改为仅一帧的顶部中间,而不是更改它们的位置。我调试了它,知道它来自 validate()。如果我手动使用 validate() ,它也会在没有操作的情况下发生。

所以这里是面板中使用的组件的代码:

import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingConstants;
import javax.swing.UIManager;

import org.pentaho.reporting.engine.classic.core.DataFactory;
import org.pentaho.reporting.engine.classic.core.designtime.DataSourcePlugin;

import com.inform_ac.utils.misc.gui.resizer.ComponentResizer;



/**
 * AButton is a JAVA-Swing component with integrated functional buttons.
 */
public class AButton extends JPanel {

/**
 * SerialVersionUID: 111111111L
 */
protected static final long serialVersionUID = 111111111L;

/**
 * Standard font for displaying text.
 */
protected Font standardFont = new Font("Dialog", Font.PLAIN, 12);

/**
 * Defining functional JButtons to delete and edit a AButton.
 */
protected ADeleteButton delBtn = new ADeleteButton(this);
protected JButton editBtn = new JButton();
protected String[] editOptionNames = { "Connect", "Deconnect", "Edit" };
protected JPopupMenu popupmenu = new JPopupMenu();
protected Dimension minDimension = new Dimension(120,120);
protected Point location = new Point();

protected DataFactory dataFactory;
protected DataSourcePlugin dataSourcePlugin;


/**
 * Mode: 0 - moving 
     *       1 - connecting
 */
protected int mode = 0;

/**
 * Defining the label for displaying OK or error images.
 */
protected JLabel lblIcon = new JLabel();

protected final JLabel lblInfo1 = new JLabel();
protected final JLabel lblInfo2 = new JLabel();
protected final JLabel lblInfo3 = new JLabel();

public final JButton connectBtn_right = new JButton();
public final JButton connectBtn_left = new JButton();

protected AButton parent;
protected ArrayList<AButton> children = new ArrayList<AButton>();

/**
 * Identifier
 */
protected int id = 0;

/**
 * Constructor with given start coordinates.
 * 
 * @param X
 *            - coordinate
 * @param Y
 *            - coordinate
 */
public AButton(int X, int Y, int index) {
    this.id = index;
    location = new Point(X,Y);
    setBounds(location.x, location.y, minDimension.width, minDimension.height);
    init();

}

/**
 * Private method to initialize main components.
 */
private void init() {
    initPnl();
    initBtns();
    setVisible(true);
    setFocusable(true);
}

/**
 * Private method to initialize the main panel.
 */
private void initPnl() {
    setBackground(UIManager.getColor("InternalFrame.activeTitleBackground"));
    setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
    setPreferredSize(minDimension);
    setBorder(UIManager.getBorder("CheckBox.border"));
    setFont(standardFont);
    setLayout(null);
}

/**
 * Private method to initialize functional {@linkplain JButton}.
 */
private void initBtns() {
    initEditBtn();
    initDelBtn();
    initIconPnl();
    initConnectorBtns();
}

/**
 * Private method to initialize the delete button. Method have to refresh
 * the size of this AButton to set the button on the top right corner of
 * this AButton.
 */
private void initDelBtn() {
    delBtn.setBounds(getWidth() - 18 - 2, 2, 18, 18);
    delBtn.setFont(standardFont);
    delBtn.setBackground(null);
    delBtn.setBorderPainted(false);
    delBtn.setBorder(null);
    delBtn.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
    delBtn.setPreferredSize(new Dimension(16, 16));
    delBtn.setMinimumSize(new Dimension(12, 12));
    delBtn.setMaximumSize(new Dimension(20, 20));
    delBtn.setIcon(new ImageIcon(AButton.class
            .getResource("/javax/swing/plaf/metal/icons/ocean/close.gif")));
    add(delBtn);
}

/**
 * Private method to initialize the edit button.
 */
private void initEditBtn() {
    initPopupmenu();
    initMouseListener();
    editBtn.setBounds(2,2,21,21);
    editBtn.setFont(standardFont);
    editBtn.setBorder(null);
    editBtn.setBorderPainted(false);
    editBtn.setBackground(UIManager
            .getColor("InternalFrame.activeTitleGradient"));
    editBtn.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
    editBtn.setAlignmentX(Component.CENTER_ALIGNMENT);
    editBtn.setPreferredSize(new Dimension(21, 21));
    editBtn.setMinimumSize(new Dimension(18, 18));
    editBtn.setMaximumSize(new Dimension(25, 25));
    editBtn.setIcon(new ImageIcon("C:\\Users\\akaradag\\Pictures\\JavaIcon\\icon_bearbeiten.gif"));
add(editBtn);
}

protected void initPopupmenu(){
    for(int i = 0; i < editOptionNames.length; i++) {
        popupmenu.add(new AbstractAction(editOptionNames[i]) {

            private static final long serialVersionUID = 5550466652812249477L;

            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getActionCommand().equals("Connect")) {
                    if (mode == 1) {
                        mode = 0;
                        showConnectors();
                    } else {
                        mode = 1;
                        showConnectors();
                    }
                } else if (e.getActionCommand().equals("Deconnect")) {
                    resetConnections();
                }
                else if(e.getActionCommand().equals("Edit")) {

                }
            }

        });
    }
}


protected void initMouseListener()
{
    editBtn.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            popupmenu.show(e.getComponent(), e.getX(), e.getY());
        }
    });
}

/**
 * Private method to display or not display the connector buttons
 */
public void showConnectors() {
    boolean connect = false;
    if (mode == 1) {
        connect = true;
    }
    connectBtn_left.setVisible(connect);
    connectBtn_right.setVisible(connect);
}

/**
 * Private method to initialize the connector buttons
 */
private void initConnectorBtns() {
    connectBtn_right.setCursor(Cursor
            .getPredefinedCursor(Cursor.DEFAULT_CURSOR));
    connectBtn_right.setVisible(false);
    connectBtn_right.setPreferredSize(new Dimension(15, 15));
    connectBtn_right.setMinimumSize(new Dimension(12, 12));
    connectBtn_right.setMaximumSize(new Dimension(15, 15));
    connectBtn_right.setFont(new Font("Dialog", Font.PLAIN, 12));
    connectBtn_right.setBorderPainted(false);
    connectBtn_right.setBorder(null);
    connectBtn_right.setBackground(SystemColor.activeCaption);
    connectBtn_right
            .setBounds(getWidth() - 16, getHeight() / 2 - 5, 15, 15);
    add(connectBtn_right);
    connectBtn_left.setCursor(Cursor
            .getPredefinedCursor(Cursor.DEFAULT_CURSOR));

    connectBtn_left.setVisible(false);
    connectBtn_left.setPreferredSize(new Dimension(25, 25));
    connectBtn_left.setMinimumSize(new Dimension(12, 12));
    connectBtn_left.setMaximumSize(new Dimension(15, 15));
    connectBtn_left.setFont(new Font("Dialog", Font.PLAIN, 12));
    connectBtn_left.setBorderPainted(false);
    connectBtn_left.setBorder(null);
    connectBtn_left.setBackground(SystemColor.activeCaption);
    connectBtn_left.setBounds(2, getHeight() / 2 - 5, 15, 15);
    add(connectBtn_left);
}

/**
 * Private method to initialize the {@linkplain JLabel} for displaying
 * informations.
 */
private void initIconPnl() {
    lblIcon.setHorizontalTextPosition(SwingConstants.CENTER);
    lblIcon.setHorizontalAlignment(SwingConstants.CENTER);
    lblIcon.setAlignmentX(Component.CENTER_ALIGNMENT);
    lblIcon.setIcon(new ImageIcon(AButton.class
            .getResource("/javax/swing/plaf/metal/icons/ocean/error.png")));
    lblIcon.setBorder(null);
    lblIcon.setFont(new Font("Dialog", Font.PLAIN, 12));

    lblIcon.setBounds(getWidth() / 4, 3, getWidth() / 2,
            getHeight() / 4 + 2);
    lblIcon.setLayout(null);
    add(lblIcon);

    lblInfo1.setFont(new Font("Tahoma", Font.BOLD, getHeight() / 10));
    lblInfo1.setForeground(SystemColor.desktop);
    lblInfo1.setBounds(22, getHeight() / 2 - 5, getWidth() - 42,
            getHeight() / 8);
    add(lblInfo1);

    lblInfo2.setFont(new Font("Tahoma", Font.BOLD, getHeight() / 10));
    lblInfo2.setForeground(Color.BLACK);
    lblInfo2.setBounds(10, getHeight() / 2 - 5 + getHeight() / 8 + 5,
            getWidth() - 20, getHeight() / 8);
    add(lblInfo2);

    lblInfo3.setFont(new Font("Tahoma", Font.BOLD, getHeight() / 10));
    lblInfo3.setForeground(Color.BLACK);
    lblInfo3.setBounds(10, getHeight() / 2 - 5 + 2 * (getHeight() / 8 + 5),
            getWidth() - 20, getHeight() / 8);
    add(lblInfo3);
}

public String getLblInfo(int index) {
    if (index == 1) {
        return lblInfo1.getText();
    } else if (index == 2) {
        return lblInfo2.getText();
    } else {
        return lblInfo3.getText();
    }
}

public void setLblInfo(String text, int index) {
    if (index == 1) {
        lblInfo1.setText(text);
    } else if (index == 2) {
        lblInfo2.setText(text);
    } else {
        lblInfo3.setText(text);
    }
}

public Point getLocation() {
    return new Point(getX(), getY());
}

public Point getInputLocation() {
    return connectBtn_left.getLocation();
}

/**
 * Methode um die Location des Objektes zu ändern und dies auch zu repainten. 
 * Dient dazu damit der Fehler das wenn ein Objekt gelöscht wird die restlichen in die Mitte
 * wandern.
 */
public void setLocation(Point p){
    location = p;
}

public Point getOutputLocation() {
    return connectBtn_right.getLocation();
}

public int getMode() {
    return mode;
}

public void setMode(int mode) {
    this.mode = mode;
    showConnectors();
}

public JButton getDelBtn() {
    return delBtn;
}

public int getIndex() {
    return id;
}

public void setIndex(int index) {
    this.id = index;
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    this.setLocation(location.x, location.y);
    if (lblInfo1.getText().equals("Join")) {
        if (children.size() == 2) {
            lblIcon.setIcon(new ImageIcon(
                    "C:\\Users\\akaradag\\Pictures\\JavaIcon\\ok-icon.png"));
        } else if (children.size() > 2) {
            lblIcon.setIcon(new ImageIcon(
                    AButton.class
                            .getResource("/javax/swing/plaf/metal/icons/ocean/warning.png")));
        } else {
            lblIcon.setIcon(new ImageIcon(
                    AButton.class
                            .getResource("/javax/swing/plaf/metal/icons/ocean/error.png")));
        }
    } else if (lblInfo1.getText().equals("JDBC")
            || lblInfo1.getText().equals("File")) {
        if (parent != null) {
            lblIcon.setIcon(new ImageIcon(
                    "C:\\Users\\akaradag\\Pictures\\JavaIcon\\ok-icon.png"));
        } else {
            lblIcon.setIcon(new ImageIcon(
                    AButton.class
                            .getResource("/javax/swing/plaf/metal/icons/ocean/error.png")));
        }
    }
}

public void setOutput(AButton out) {
    parent = out;
}

public AButton getOutput() {
    return parent;
}

public void addInput(AButton input) {
    if (!contains(input)) {
        this.children.add(input);
    }
}

private boolean contains(AButton in) {
    for (int i = 0; i < this.children.size(); i++) {
        if (this.children.get(i).getIndex() == in.getIndex()) {
            return true;
        }
    }
    return false;
}

public ArrayList<AButton> getInput() {
    return this.children;
}

public void removeFromInput(AButton remove) {
    for (int i = 0; i < this.children.size(); i++) {
        if (this.children.get(i) != null) {
            if (this.children.get(i).getIndex() == remove.getIndex()) {
                this.children.remove(i);
            }
        }
    }
}

public void resetConnections() {
    if (parent != null) {
        ArrayList<AButton> in = parent.getInput();
        for (int i = 0; i < in.size(); i++) {
            if (in.get(i).getIndex() == id) {
                in.remove(i);
            }
        }
        parent = null;
    }

    for (int i = 0; i < this.children.size(); i++) {
        this.children.get(i).setOutput(null);
        this.children.get(i).repaint();
    }
    this.children = new ArrayList<AButton>();

//      if(connectionsDeletedNotify != null)
//          connectionsDeletedNotify.actionPerformed(new ActionEvent(this, 0, "Deconnect"));
}

/**
 * Setter for the DataFactory
 * @param df
 */
public void setDataFactory(DataFactory df)
{
    this.dataFactory = df;
}

/**
 * Getter for the DataFactory
 * @return
 */
public DataFactory getDataFactory()
{
    return this.dataFactory;
}

public DataSourcePlugin getDataSourcePlugin() {
    return dataSourcePlugin;
}

public void setDataSourcePlugin(DataSourcePlugin dataSourcePlugin) {
    this.dataSourcePlugin = dataSourcePlugin;
}
}

这是主面板的代码

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.util.ArrayList;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;

import org.pentaho.reporting.designer.core.settings.WorkspaceSettings;
import org.pentaho.reporting.engine.classic.core.DataFactory;
import org.pentaho.reporting.engine.classic.core.MasterReport;
import org.pentaho.reporting.engine.classic.core.designtime.DataSourcePlugin;
import org.pentaho.reporting.engine.classic.core.designtime.DefaultDataFactoryChangeRecorder;
import org.pentaho.reporting.engine.classic.core.metadata.DataFactoryMetaData;
import org.pentaho.reporting.engine.classic.core.metadata.DataFactoryRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.inform_ac.reporting.datasource.dataintegrator.frontend.DataintegratorDesignTimeContext;
import com.inform_ac.reporting.datasource.dataintegrator.frontend.component.AButton;
import com.inform_ac.reporting.datasource.dataintegrator.frontend.component.AConfirmDialog;
import com.inform_ac.reporting.datasource.dataintegrator.frontend.component.ADeleteButton;

public class DataintegratorMainPanel extends JPanel {


DataintegratorDesignTimeContext context;
JPopupMenu popmen = new JPopupMenu();

JMenuItem menu1 = new JMenuItem("Add new Datasource:");
JMenuItem menu2 = new JMenuItem("Join");

Dimension dim = new Dimension();
Point holdingPoint , point1, point2;;

/**
 * ArrayList für die visuellen Datasources
 */
ArrayList<AButton> abuttonList = new ArrayList<AButton>();

/**
 * Nummerierungen der abuttons
 */
int index = 0;

/**
 * The <code>Logger</code> of this instance
 */
protected final static Logger LOGGER = LoggerFactory.getLogger(DataintegratorQueryPanel.class);

private static final long serialVersionUID = 4705352682546516889L;

public DataintegratorMainPanel() {
    initPopupMenu();
    initMouseListener();
}

protected void initMouseListener()
{
    this.addMouseListener(new MouseAdapter() {

        @Override
        public void mouseReleased(MouseEvent e) {
            if (e.getButton() == MouseEvent.BUTTON3){
                popmen.show(e.getComponent(), e.getX(), e.getY());
            }
        }
    });
}

/**
 * Überschrift bei Rechtsklick
 * @param header
 * @return JComponent
 */
protected JComponent createHeader(String header) {
    JLabel label = new JLabel(header);
    label.setFont(label.getFont().deriveFont(Font.BOLD,14));
    label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

    return label;
}

protected void giveMouseListenerTo(AButton button) {        
    button.addMouseMotionListener(new MouseAdapter() {

        @Override 
        public void mouseDragged(MouseEvent me) {
            super.mouseDragged(me);
            AButton tmp = (AButton) me.getSource();

            //Mode Moving
            if(tmp.getMode()==0){

            Point point = getMousePosition();

            //Über den Rand raus
            if(point != null) {
                point.x = point.x - holdingPoint.x;
                point.y = point.y - holdingPoint.y;

                if(point.x >= 0 && point.y >= 0) {
                    tmp.setLocation(point);
                }
                //LOGGER.info(""+point);
            }
            }
            else if (tmp.getMode()==1) {
                point2 = getMousePosition();
            }
            repaint();
        }
    });


    button.addMouseListener(new MouseAdapter() {

        @Override
        public void mousePressed(MouseEvent me) {
            super.mousePressed(me);

            AButton tmp = (AButton) me.getSource();
            if (tmp.getMode() == 0) {
                holdingPoint = tmp.getMousePosition();
            }

            else if (tmp.getMode() == 1) {
                Point tmp_point = tmp.getLocation();

                point1 = new Point(tmp.connectBtn_right.getLocation().x+tmp_point.x,tmp.connectBtn_right.getLocation().y+tmp_point.y);
                LOGGER.info("point1: "+point1);
            }
        }

        @Override
        public void mouseReleased(MouseEvent me) {
            super.mouseReleased(me);
            try {
                AButton destination = (AButton) getComponentAt(getMousePosition());
                AButton source = (AButton) me.getSource();
                if (destination != null && source.getMode() == 1) {

                    // Hier muss der Baum verkettet werden
                    if (destination != source) {
                        destination.addInput(source);

                        if (source.getOutput() == null) {
                            source.setOutput(destination);
                        } else {
                            AButton tmp = source.getOutput();
                            tmp.removeFromInput(source);
                            source.setOutput(destination);
                        }
                        source.setMode(0);
                        destination.setMode(0);
                    }
                }
            } catch (ClassCastException e) {
                point2 = null;
            }
            point1 = null;
            point2 = null;
            repaint();
        }
    });
    repaint();
}

protected void initPopupMenu() {
    popmen.add(createHeader("Neue Datasource"));
    popmen.addSeparator();

     context = new DataintegratorDesignTimeContext(new MasterReport());

    final DataFactoryMetaData[] datas = DataFactoryRegistry.getInstance()
            .getAll();

    for (final DataFactoryMetaData data : datas) {

        // Some of the DataFactories are not needed
        if (data.isHidden()) {
            continue;
        } else if (!WorkspaceSettings.getInstance().isShowExpertItems()
                && data.isExpert()) {
            continue;
        } else if (!WorkspaceSettings.getInstance().isShowDeprecatedItems()
                && data.isDeprecated()) {
            continue;
        } else if (!WorkspaceSettings.getInstance()
                .isExperimentalFeaturesVisible() && data.isExperimental()) {
            continue;
        } else if (!data.isEditorAvailable()) {
            continue;
        }

        if (data.getDisplayName(getLocale()).equals("Dataintegrator")) {
            continue;
        }

        JMenuItem item = new JMenuItem(new AbstractAction(
                data.getDisplayName(getLocale())) {

                    private static final long serialVersionUID = 7700562297221703939L;

                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        Point mousePos = getMousePosition();
                        final AButton tmp = new AButton(mousePos.x,mousePos.y,index++);

                        // Action listener hier und nicht in die for schleife
                        tmp.getDelBtn().addActionListener(new ActionListener() {
                            public void actionPerformed(ActionEvent arg0) {
                                ADeleteButton tmp_1 = (ADeleteButton) arg0
                                        .getSource();
                                AButton source = tmp_1.getAbutton();
                                AConfirmDialog dialog = new AConfirmDialog();

                                int opt = dialog.getState();
                                if (opt == 1) {
                                    for (int i = 0; i < abuttonList.size(); i++) {
                                        if (source.getIndex() != abuttonList.get(i)
                                                .getIndex()) {

                                            if (abuttonList.get(i).getOutput() != null
                                                    && abuttonList.get(i).getOutput()
                                                            .getIndex() == source
                                                            .getIndex()) {
                                                abuttonList.get(i).setOutput(null);
                                            }
                                            abuttonList.get(i).removeFromInput(source);
                                        }
                                    }

                                    // seperat erst die referenzen löschen dann das
                                    // objekt aus der liste
                                    for (int i = 0; i < abuttonList.size(); i++) {
                                        if (source.getIndex() == abuttonList.get(i)
                                                .getIndex()) {
                                            abuttonList.remove(i);
                                            source.setVisible(false);
                                            source.setEnabled(false);
                                        }
                                    }
                                }
                            }
                        });

                        LOGGER.info("--> data: " + data);
                        final DataSourcePlugin editor = data.createEditor();
                        LOGGER.info("--> editor: " + editor);
                        final DefaultDataFactoryChangeRecorder recorder = new DefaultDataFactoryChangeRecorder();

                        final DataFactory dataFactory = editor.performEdit(context,
                                null, null, recorder);
                        LOGGER.info("--> datafactory: " + dataFactory);

                        // Falls die Datafactory initialisiert werden konnte
                        if (dataFactory != null) {
                            tmp.setDataSourcePlugin(editor);
                            tmp.setDataFactory(dataFactory);

                            add(tmp);

                            //LOGGER.info("New datafact"+mousePos);

                            abuttonList.add(tmp);

                            //Moving listener
                            giveMouseListenerTo(tmp);
                            validate();
                        }


                    }
        });
        popmen.add(item);
    }
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g;

        g2d.setStroke(new BasicStroke(1.5f));


        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        Line2D tmp_line;
        for (int i = 0; i < abuttonList.size(); i++) {
            if (abuttonList.get(i).getOutput() != null) {
                g2d.setStroke(new BasicStroke(1.5f));
                int x1 = abuttonList.get(i).getLocation().x
                        + abuttonList.get(i).connectBtn_right.getLocation().x;
                int y1 = abuttonList.get(i).getLocation().y
                        + abuttonList.get(i).connectBtn_right.getLocation().y;
                int x2 = abuttonList.get(i).getOutput().getLocation().x
                        + abuttonList.get(i).getOutput().connectBtn_left
                                .getLocation().x - 4;
                int y2 = abuttonList.get(i).getOutput().getLocation().y
                        + abuttonList.get(i).getOutput().connectBtn_left
                                .getLocation().y;

                tmp_line = new Line2D.Double(x1, y1, x2, y2);
                double m = (y2 - y1) / (double) (x2 - x1);
                //logger.info("m: "+m);

                int vz = x2-x1;
                //LOGGER.info("vz: "+vz);

                if(vz<0)
                {
                    vz = 20;
                }
                else if (vz>0){
                    vz = -20;
                }

                if(m<4 && m>-4) {

                    Point p = new Point(x2 -20, (int) (y1 + m * (x2 - x1 - 20)));
                    //logger.info(p.toString());

                    Line2D tmp2_line = new Line2D.Double(x2, y2, x2 + vz,
                            p.y + 3);
                    //logger.info("x2: "+x2+", y2: "+y2+", p.y:"+p.y);

                    Line2D tmp3_line = new Line2D.Double(x2, y2, x2 + vz,
                            p.y - 3);
                    //logger.info("x2: "+x2+", y2: "+y2+", p.y:"+p.y);

                    g2d.setPaint(Color.BLACK);
                    g2d.draw(tmp2_line);
                    g2d.draw(tmp3_line);
                }
                g2d.draw(tmp_line);

            }
        }
        if (point1 != null && point2 != null) {
            Line2D line2d = new Line2D.Double(point1, point2);
            g2d.setPaint(Color.RED);
            g2d.setStroke(new BasicStroke(1.5f));// set stroke size
            g2d.draw(line2d);
        }
}
}

因此,如果我单击editBtn 并单击例如连接,则会发生错误。它会重新绘制整个面板,并且面板中的按钮垂直位于面板的中间顶部,对于某些帧,它会返回到保存在对象本身中的位置。

我也可以使用 validate() 重现错误。

我不明白这里有什么问题。为什么在验证后更改主面板中组件的位置?

抱歉,如果代码不是 SSCCE,但如果没有 pentaho 库,我将无法使其工作......

4

2 回答 2

1

好的,我修好了。

问题是 JPanel 的默认布局管理器。

在我将其更改为setLayout(null);问题消失后。

于 2013-08-28T11:46:13.823 回答
0
  1. 我建议使用布局管理器,在任何方面它都是可取的;一开始可能需要一些时间,但值得。对于简单的用例,内置的,如BorderLayoutGridBagLayout可能就足够了。但是,为了获得更多控制,请尝试MigLayout:完整、优雅和精确。( http://www.miglayout.com/ )

  2. 如果你问为什么,JavaDoc 有它:

无效 java.awt.Container.validate()

验证此容器及其所有子组件。

验证容器意味着布置其子组件。布局相关的更改,例如设置组件的边界,或将组件添加到容器中,会自动使容器失效。请注意,容器的祖先也可能无效(有关详细信息,请参阅 Component.invalidate。)因此,要恢复层次结构的有效性,应在层次结构的最顶层无效容器上调用 validate() 方法。

验证容器可能是一个相当耗时的操作。出于性能原因,开发人员可能会推迟层次结构的验证,直到一组与布局相关的操作完成,例如在将所有子项添加到容器之后。

如果此 Container 无效,则此方法调用 validateTree 方法并将此 Container 标记为有效。否则,不执行任何操作。

覆盖:组件中的 validate()

于 2017-08-30T09:43:02.157 回答