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

不羁的心 提交于 2019-12-13 04:38:18

问题


When I run my program from eclipse the GUI is perfect and all is swell. But when I export into jar file (with all dependencies) it runs, but the GUI is just strange and some of the UI items don't even appear (as you'll see in the screen shots).

I have tried exporting as runnable jar, or as a normal jar with my own manifest file, and I've tried compiling and linking into a jar manually from terminal (I'm using linux mint by the way). My project compliance is set on java 1.8, and I have java 1.8 in my PATH, so it wouldn't seem as though its a version mismatch.

Strangely enough, sending all my source code to a friend running windows, he is able to link to a jar and run it, and it works perfectly. But the problem isn't specific to my machine because running it on another linux machine gives the exact same GUI faults.

If anyone can help me out with this it would be much appreciated.

/**
 * @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();
                    }


                }
            }
        }       
    }
}

How it looks in eclipse:

How it looks running from the JAR:


回答1:


Ok, I've tried your code (after stripping loads of non-relevant code) and it definitely is a GTK version issue.

You can verify this by doing the following:

  • Open a terminal and type:

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

This will run your code using GTK2 instead of GTK3 and it should look like what you'd expect.

However, for the long-term you should look into making your application work with GTK3 as well. This may involve changing layouts etc. and is more or less a trial-and-error process.



来源:https://stackoverflow.com/questions/33220937/running-swt-gui-from-jar-file-is-different-and-faulty-but-works-perfectly-runn

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!