运行 jar 文件中的 SWT GUI 不同(并且有问题)但在 eclipse 中工作得很好 运行

Running SWT GUI from jar file is different (and faulty) but works perfectly running from eclipse

当我 运行 我的程序来自 eclipse 时,GUI 是完美的,一切都很好。但是当我导出到 jar 文件(具有所有依赖项)时,它 运行s,但是 GUI 很奇怪并且一些 UI 项目甚至没有出现(因为你'会在屏幕截图中看到)。

我已经尝试导出为 运行nable jar,或者作为带有我自己的清单文件的普通 jar,并且我已经尝试从终端手动编译并 linking 到 jar(我顺便说一句,我正在使用 linux mint)。我的项目合规性设置为 java 1.8,我的 PATH 中有 java 1.8,所以它看起来不像是版本不匹配。

奇怪的是,将我所有的源代码发送给 运行 宁 windows 的朋友,他能够 link 到一个 jar 和 运行 它,它工作完美。但是这个问题并不特定于我的机器,因为 运行 在另一台 linux 机器上使用它会给出完全相同的 GUI 错误。

如果有人能帮我解决这个问题,我将不胜感激。

/**
 * @author Garrit Nieuwoudt
 */

import java.io.File;
import java.util.ArrayList;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Sash;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;



public class MainPage {

    private String iconDir ="."+File.separator+"images"+File.separator;

    private Display disp;
    private Shell shell;
    private DatabaseHelper D;
    private Tree tree;
    private MainPage self;
    private final Sash sash;
    private Image icon;
    private Table individualTable;
    private Table markerTable;
    private CTabFolder folder;
    private Table resultTable;
    private Table resultCheckTable;
    private ArrayList<TestResult> allTestResults;


    public MainPage(DatabaseHelper Dat){
        allTestResults=new ArrayList<TestResult>();
        this.self=this;
        this.disp=Display.getCurrent();
        D=Dat;
        shell =new Shell(disp);


        shell.setText(User.getCurrentUser().getName()+" - Genome Project");

        icon=new Image(disp,iconDir+"blueDNA.png");
        shell.setImage(icon);

        FormLayout layout = new FormLayout();
        shell.setLayout(layout);

        createMenuBar();

        sash = new Sash(shell, SWT.BORDER | SWT.VERTICAL |SWT.TRANSPARENT);

        FormData formData = new FormData();
        formData.top = new FormAttachment(0,40);
        formData.left = new FormAttachment(15);
        formData.bottom=new FormAttachment(100);
        formData.width=3;

        sash.setLayoutData(formData);

        sash.addListener(SWT.Selection, new Listener () {
            public void handleEvent(Event e) {
                sash.setBounds(e.x, e.y, e.width, e.height);
                if(e.x<=100){
                    e.doit=false;

                }else{
                    sash.setEnabled(true);
                    FormData formData = new FormData();
                    formData.top = new FormAttachment(0, 0);
                    formData.left = new FormAttachment(0,e.x);
                    formData.bottom = new FormAttachment(100, 0);
                    formData.width=3;
                    sash.setLayoutData(formData);
                    shell.layout(true);

                }
            }
        });

        tree = new Tree(shell, SWT.VIRTUAL | SWT.BORDER );
        tree.setToolTipText("Double click any tree item to load data to the table");

        FormData treeData=new FormData();
        treeData.left=new FormAttachment(0,3);
        treeData.bottom=new FormAttachment(100,-50);
        treeData.top=new FormAttachment(0,40);
        treeData.right=new FormAttachment(sash,-1,SWT.LEFT);
        tree.setLayoutData(treeData);


        setTree();

        tree.addListener(SWT.MouseDoubleClick, new Listener() {

            @Override
            public void handleEvent(Event event) {

                int activeTab=folder.getSelectionIndex();

                // TODO Auto-generated method stub
                Point p=new Point(event.x,event.y);
                TreeItem FT=tree.getItem(p);
                if (activeTab==0) {
                    if (FT != null) {
                        individualTable.removeAll();
                        markerTable.removeAll();
                        int famIndex;
                        int dataIndex;
                        int fn;

                        if (FT.getParentItem() != null) {
                            famIndex = FT.getParentItem().indexOf(FT);
                            dataIndex = tree.indexOf(FT.getParentItem());
                            fn = famIndex + 1;
                        } else {
                            dataIndex = tree.indexOf(FT);
                            famIndex = 0;
                            fn = User.getCurrentUser().getDS().get(dataIndex).getFams().size();
                        }

                        for (int fi = famIndex; fi < fn; fi++) {
                            Family fam = User.getCurrentUser().getDS()
                                    .get(dataIndex).getFams().get(fi);
                            for (int ii = 0; ii < fam.getMembers().size(); ii++) {

                                Individual ind = fam.getMembers().get(ii);
                                TableItem item = new TableItem(individualTable,
                                        SWT.NULL);
                                item.setData("DS_ID", dataIndex);
                                item.setData("famIndex", fi);
                                item.setData("indIndex", ii);
                                item.setText(0, fam.getID());
                                item.setText(1, ind.getID());
                                item.setText(2, ind.getPatID());
                                item.setText(3, ind.getMatID());
                                item.setText(4, (ind.getGender() == 1) ? "Male"
                                        : (ind.getGender() == 2) ? "Female"
                                                : "Other");
                                item.setText(
                                        5,
                                        ind.getPhenotype() == 2 ? "Affected"
                                                : (ind.getPhenotype() == 1) ? "Unaffected"
                                                        : "Missing");
                            }
                        }

                        for (int loopIndex = 0; loopIndex < individualTable.getColumnCount(); loopIndex++) {
                            individualTable.getColumn(loopIndex).pack();
                        }
                    }
                }else if(activeTab==1){
                    if (FT != null) {
                        resultTable.removeAll();
                        resultCheckTable.removeAll();
                        allTestResults.clear();
                        int famIndex;
                        int dataIndex;
                        int fn;

                        if (FT.getParentItem() != null) {
                            famIndex = FT.getParentItem().indexOf(FT);
                            dataIndex = tree.indexOf(FT.getParentItem());
                            fn = famIndex + 1;
                        } else {
                            dataIndex = tree.indexOf(FT);
                            famIndex = 0;
                            fn = User.getCurrentUser().getDS().get(dataIndex).getFams().size();
                        }

                        for (int fi = famIndex; fi < fn; fi++) {
                            Family fam = User.getCurrentUser().getDS().get(dataIndex).getFams().get(fi);

                            TestResult res=GenomeTests.recTest(fam);
                            allTestResults.add(res);
                            res=GenomeTests.domTest(fam);
                            allTestResults.add(res);

                            //ArrayList<Marker> resMarkers=res.getCandidateMarkers();



                        }
                        for (int ri = 0; ri < allTestResults.size(); ri++) {
                            TestResult res=allTestResults.get(ri);
                            Family fam=res.getFam();
                            ArrayList<Marker> resMarkers=res.getCandidateMarkers();
                            ArrayList<Integer> resIndices=res.getIndices();
                            res.setDataIndex(dataIndex);
                            String label="";
                            if(res.getTestType()==1){
                                label="Recessive";

                            }else if(res.getTestType()==2){
                                label="Dominant";
                            }

                            for (int mi = 0; mi < resMarkers.size(); mi++) {

                                Marker mrk = resMarkers.get(mi);
                                TableItem item = new TableItem(resultTable,
                                        SWT.NULL);

                                item.setData("DS_ID", res.getDataIndex());
                                item.setData("fam", fam);
                                //change this in table listener
                                item.setData("markIndex",resIndices.get(mi));
                                item.setText(0, fam.getID());
                                item.setText(1, mrk.getChromNum());
                                item.setText(2, mrk.getSNP());
                                item.setText(3, mrk.getBPPos() + "");
                                item.setText(4, label);
                            }
                        }

                        for (int loopIndex = 0; loopIndex < resultTable.getColumnCount(); loopIndex++) {
                            resultTable.getColumn(loopIndex).pack();
                        }



                    }
                }
            }
        });

        createTabFolder();  

        shell.open();

        shell.forceFocus();

        while(!shell.isDisposed()){
            if(!disp.readAndDispatch()){
                disp.sleep();
            }
        }
        disp.dispose();
    }


    public void createMenuBar(){
        Menu menuBar = new Menu(shell, SWT.BAR);
        MenuItem fileMenuHeader = new MenuItem(menuBar, SWT.CASCADE);
        fileMenuHeader.setText("&File");

        Menu fileMenu = new Menu(shell, SWT.DROP_DOWN);
        fileMenuHeader.setMenu(fileMenu);

        MenuItem fileImportItem = new MenuItem(fileMenu, SWT.PUSH);
        fileImportItem.setText("&Import");
        fileImportItem.setToolTipText("Import a new set of data into the program");
        fileImportItem.setImage(new Image(disp,iconDir+"importIcon.png"));
        MenuItem fileSignoutItem = new MenuItem(fileMenu, SWT.PUSH);
        fileSignoutItem.setText("&Sign out");
        fileSignoutItem.setToolTipText("Return to the Login page");
        MenuItem helpMenuHeader = new MenuItem(menuBar, SWT.CASCADE);
        helpMenuHeader.setText("&Help");

        Menu helpMenu = new Menu(shell, SWT.DROP_DOWN);
        helpMenuHeader.setMenu(helpMenu);

        MenuItem helpGetHelpItem = new MenuItem(helpMenu, SWT.PUSH);
        helpGetHelpItem.setText("&Get Help");


        fileImportItem.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e){
                new ImportPage(D,self);

            }


        });

        fileSignoutItem.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e){
                shell.dispose();
                new User(-1,null);
                new LoginPage(D);
            }


        });

        shell.setMenuBar(menuBar);
    }

    public void createTabFolder(){
        folder = new CTabFolder(shell,  SWT.BORDER );
        folder.setSimple(false);

        FormData tabData=new FormData();
        tabData.left=new FormAttachment(sash,0,SWT.RIGHT);
        tabData.right=new FormAttachment(100,-10);
        tabData.top=new FormAttachment(tree,0,SWT.TOP);
        tabData.bottom=new FormAttachment(tree,0,SWT.BOTTOM);
        folder.setLayoutData(tabData);

        //Tab 1
        CTabItem tab1 = new CTabItem(folder,SWT.NONE);
        tab1.setText("Details");
        tab1.setImage(new Image(disp,iconDir+"smallDetails.png"));
        folder.setSelection(tab1);
        // Create the SashForm with HORIZONTAL
        SashForm ssh=new SashForm(folder,SWT.HORIZONTAL);    

        //Tab 2
        CTabItem tab2 = new CTabItem(folder, SWT.NULL);
        tab2.setText("Genome Analysis");
        tab2.setImage(new Image(disp,iconDir+"DNAtwist.png"));
        setUpAnalysisPage(folder, tab2);

//_______________________________________________________________________       

        individualTable = new Table(ssh,  SWT.BORDER | SWT.V_SCROLL| SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
        individualTable.setHeaderVisible(true);
        individualTable.setLinesVisible(true);
        individualTable.setToolTipText("Click on a row to load data about the item");
        String[] indTitles = { "Family ID","Individual ID","Paternal ID","Maternal ID","Gender","Affection Status" };
        //set titles on individual details table
        setTable(individualTable,indTitles);

        markerTable = new Table(ssh,  SWT.BORDER | SWT.V_SCROLL| SWT.H_SCROLL | SWT.MULTI );
        markerTable.setHeaderVisible(true);
        markerTable.setLinesVisible(true);

        String[] markTitles = { "Chromosome", "SNP ID","Genetic distance","Base Pair Position","Allele 1","Allele 2" };
        //set titles on marker table
       setTable(markerTable,markTitles);

        //add listener to populate marker table with selected individual genome data
       individualTable.addListener(SWT.Selection,new Listener() {

            @Override
            public void handleEvent(Event e) {
                // TODO Auto-generated method stub


                TableItem itm=(TableItem) e.item;

                Family fam=null;
                Individual ind=User.getCurrentUser().getDS().get((int) itm.getData("DS_ID")).getFams().get((int)itm.getData("famIndex")).getMembers().get((int)itm.getData("indIndex"));


                ArrayList<Genotype> G=ind.getGeno();
                markerTable.removeAll();
                for(int i=0;i<G.size();i++){
                    TableItem mItem = new TableItem(markerTable, SWT.NULL);
                    Genotype gt=G.get(i);
                    Marker M=gt.getMarker();
                    mItem.setText(0, M.getChromNum());
                    mItem.setText(1, M.getSNP());
                    mItem.setText(2, M.getDist()+"");
                    mItem.setText(3,M.getBPPos()+"");
                    mItem.setText(4,String.valueOf(gt.getBase1()));
                    mItem.setText(5,String.valueOf(gt.getBase2()));
                }

                for (int loopIndex = 0; loopIndex < markTitles.length; loopIndex++) {
                    markerTable.getColumn(loopIndex).pack();
                }

            }

        });
        tab1.setControl(ssh);


    }

    public void setUpAnalysisPage(CTabFolder folder,CTabItem tab){
        Group comp=new Group(folder,SWT.NONE);
        FormLayout lay=new FormLayout();
        comp.setLayout(lay);

        ToolBar tools=new ToolBar(comp,SWT.HORIZONTAL | SWT.FLAT  );
        ToolItem refine=new ToolItem(tools,SWT.CHECK);
        refine.setImage(new Image(disp,iconDir+"filterIcon.png"));
        refine.setToolTipText("Click here to refine the analysis results to specific tests");

        Group refineGroup=new Group(comp,SWT.BORDER);

        refineGroup.setLayout(new RowLayout(SWT.VERTICAL));

        //ToolBar refineTools=new ToolBar(refineGroup,SWT.VERTICAL);

        //refineGroup.setBackground(disp.getSystemColor(SWT.COLOR_TRANSPARENT));


        Button check=new Button(refineGroup,SWT.CHECK );
        check.setText("Recessive Test");
        check.setSelection(true);
        Button check1=new Button(refineGroup,SWT.CHECK );
        check1.setText("Dominant Test");
       check1.setSelection(true);



        refineGroup.setVisible(false);

        FormData toolData=new FormData();
        toolData.top=new FormAttachment(0);
        toolData.left=new FormAttachment(0);
        tools.setLayoutData(toolData);

        FormData refineGroupData=new FormData();
        refineGroupData.top=new FormAttachment(tools,-10,SWT.BOTTOM);
        refineGroupData.left=new FormAttachment(tools,10,SWT.LEFT);
        refineGroup.setLayoutData(refineGroupData);

        resultTable=new Table(comp, SWT.BORDER | SWT.V_SCROLL| SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
        resultTable.setHeaderVisible(true);
        resultTable.setLinesVisible(true);
        resultTable.setToolTipText("Click on a row to load data about the item");
        setTable(resultTable,new String[]{"Family ID","Chromosome Number","SNP","Base Pair Position","Indicating Test"});

        FormData tableData=new FormData();
        tableData.top=new FormAttachment(tools,0,SWT.BOTTOM);
        tableData.left=new FormAttachment(0);
        tableData.bottom=new FormAttachment(100);
        tableData.right=new FormAttachment(60);
        resultTable.setLayoutData(tableData);

        resultCheckTable=new Table(comp, SWT.BORDER | SWT.V_SCROLL| SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
        resultCheckTable.setHeaderVisible(true);
        resultCheckTable.setLinesVisible(true);
        setTable(resultCheckTable,new String[]{"Family ID","Individual ID","Affection Status","Allele 1","Allele 2"});

        FormData checkTableData=new FormData();
        checkTableData.top=new FormAttachment(tools,0,SWT.BOTTOM);
        checkTableData.left=new FormAttachment(resultTable,0,SWT.RIGHT);
        checkTableData.bottom=new FormAttachment(100);
        checkTableData.right=new FormAttachment(100);
        resultCheckTable.setLayoutData(checkTableData);


        refine.addListener( SWT.Selection, new Listener() {
            public void handleEvent(Event event) {

                boolean refineStatus;
                refineStatus=refineGroup.getVisible();

                if(refineStatus){

                    resultTable.removeAll();
                    resultCheckTable.removeAll();
                    refineGroup.setVisible(false);
                    int[] indices= new int[refineGroup.getChildren().length];
                    for(int ci=0; ci<refineGroup.getChildren().length; ci++){
                        Button chk=(Button) refineGroup.getChildren()[ci];
                        if(chk.getSelection()){
                            indices[ci]=ci+1;
                        }else{
                            indices[ci]=-1;
                        }
                    }

                    populateResults(allTestResults, indices);

                }else{

                    refineGroup.setVisible(true);
                }


            }
          });

        resultTable.addListener(SWT.Selection, new Listener() {

            @Override
            public void handleEvent(Event e) {

                TableItem itm=(TableItem) e.item;
                Family fam=(Family) itm.getData("fam");

                resultCheckTable.removeAll();
                for(int i=0;i<fam.getMembers().size();i++){
                    TableItem mItem = new TableItem(resultCheckTable, SWT.NULL);
                    Individual ind=fam.getMembers().get(i);
                    Genotype gene=ind.getGeno().get((int)itm.getData("markIndex"));
                    Marker M=gene.getMarker();
                    mItem.setText(0,fam.getID());
                    mItem.setText(1, ind.getID());
                    mItem.setText(2, ind.getPhenotype() == 2 ? "Affected": (ind.getPhenotype() == 1) ? "Unaffected": "Missing");
                    mItem.setText(3, gene.getBase1()+"");
                    mItem.setText(4,gene.getBase2()+"");
                    if(ind.getPhenotype()==2){
                        mItem.setForeground(2, disp.getSystemColor(SWT.COLOR_DARK_CYAN));
                        if(gene.getBase1()==gene.getBase2()){
                            mItem.setForeground(3, disp.getSystemColor(SWT.COLOR_DARK_CYAN));
                            mItem.setForeground(4, disp.getSystemColor(SWT.COLOR_DARK_CYAN));
                        }
                    }


                }

                for (int loopIndex = 0; loopIndex < resultCheckTable.getColumnCount(); loopIndex++) {
                    resultCheckTable.getColumn(loopIndex).pack();
                }

            }
        });


        ToolItem zoom=new ToolItem(tools,SWT.PUSH);
        zoom.setImage(new Image(disp,iconDir+"zoomIcon.png"));
        zoom.setEnabled(false); //not yet implemented



        tools.pack();
        tab.setControl(comp);
    }



    public void setTree(){

        ArrayList<DataSet> dat=User.getCurrentUser().getDS();
        tree.setItemCount(dat.size());
        for(int i=0;i<dat.size();i++){
            DataSet d=dat.get(i);
            ArrayList<Family> fam=d.getFams();
            TreeItem DT=tree.getItem(i);
            DT.setText("DataSet: "+(i+1));
            DT.setImage(new Image(disp,iconDir+"DNAdata.png"));
            DT.setItemCount(fam.size());



            for(int j=0;j<fam.size();j++){
                TreeItem FT= DT.getItem(j);
                //System.out.println(fam.get(i).getID());
                FT.setText(fam.get(j).getID());
                FT.setImage(new Image(disp,iconDir+"familyIcon.png"));
            }

        }
    }

    /**
     * Set table columns with titles
     * @param table - The table whose columns are being set
     * @param titles - The titles to set on the columns in respective order
     */
    public void setTable(Table table,String[] titles){
         for (int i = 0; i < titles.length; i++) {
                TableColumn column = new TableColumn(table, SWT.NULL);
                column.setText(titles[i]);
            }
            for (int i = 0; i < titles.length; i++) {
                table.getColumn(i).pack();
            }
    }


    public void populateResults(ArrayList<TestResult> res,int[] indices){

        for(int ti=0;ti<indices.length;ti++){
            if(indices[ti]>-1){
                for(int ri=0;ri<res.size();ri++){
                    TestResult TR=res.get(ri);
                    if(TR.getTestType()==indices[ti]){

                        Family fam=TR.getFam();
                        ArrayList<Marker> resMarkers=TR.getCandidateMarkers();
                        ArrayList<Integer> resIndices=TR.getIndices();

                        String label="";
                        if(TR.getTestType()==1){
                            label="Recessive";

                        }else if(TR.getTestType()==2){
                            label="Dominant";
                        }

                        for (int mi = 0; mi < resMarkers.size(); mi++) {

                            Marker mrk = resMarkers.get(mi);
                            TableItem item = new TableItem(resultTable,
                                    SWT.NULL);

                            item.setData("DS_ID", TR.getDataIndex());
                            item.setData("fam", fam);
                            //change this in table listener
                            item.setData("markIndex",resIndices.get(mi));
                            item.setText(0, fam.getID());
                            item.setText(1, mrk.getChromNum());
                            item.setText(2, mrk.getSNP());
                            item.setText(3, mrk.getBPPos() + "");
                            item.setText(4, label);
                        }
                    }

                    for (int loopIndex = 0; loopIndex < resultTable.getColumnCount(); loopIndex++) {
                        resultTable.getColumn(loopIndex).pack();
                    }


                }
            }
        }       
    }
}

它在日食中的样子:

从 JAR 中 运行ning 看起来如何:

好的,我试过你的代码(在剥离大量不相关的代码之后),它肯定是 GTK 版本问题。

您可以通过执行以下操作来验证这一点:

  • 打开终端并输入:

    export SWT_GTK3=0
    java -jar your-jar-file.jar
    

这将 运行 您的代码使用 GTK2 而不是 GTK3,它应该看起来像您期望的那样。

但是,从长远来看,您应该考虑让您的应用程序也与 GTK3 一起工作。这可能涉及更改布局等,并且或多或少是一个反复试验的过程。