Попытка запустить кусок кода в отдельном потоке - PullRequest
0 голосов
/ 08 января 2019

Я пытаюсь сделать простой MP3-плеер на Java (Swing) для учебных целей, и я действительно стараюсь НЕ нарушать «Принцип единой ответственности» в отношении классов, и я как-то застрял.

Моя проблема: после того, как песня завершена, я хочу перейти к следующей песне. У моего экземпляра плеера есть метод play, который он должен запустить - это отдельный поток. Этот экземпляр имеет метод isComplete (), который можно запустить в цикле while.

Экземпляр проигрывателя находится в классе "UserMainFunctions", который ничего не знает о других классах.

Вот код:

public final class UserMainFunctions implements MainFunctions {

MP3Tagger mp3Tagger = new MP3Tagger();
private FileInputStream fis;
private Player player;
private String currentPath;

public void stop() {
    if (getPlayer() != null) {
        getPlayer().close();
    }
}


@Override
public void play(String path) {

    // setCurrentPath(path);
    if (path != null) {
        try {
            stop();
            setFis(new FileInputStream(currentPath));
            setPlayer(new Player(getFis()));
            new Thread(new Runnable() {

                @Override
                public void run() {
                    try {
                        getPlayer().play();
                        while(getPlayer().isComplete()) {
                            ///increment and play


                        }

                    } catch (JavaLayerException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }
            }).start();

        } catch (FileNotFoundException | JavaLayerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    } else {
        System.out.println("Nothing to play!");
    }

}

public String getCurrentPath() {
    return currentPath;
}

public void setCurrentPath(String currentPath) {
    this.currentPath = currentPath;
}

@Override
public List<String> getID3V1TAG(String path) {
    if (path != null) {
        return mp3Tagger.getID3V1TAG_List(path);
    } else {
        return null;
    }
}

@Override
public void openDir() {


}

public Player getPlayer() {
    return player;
}

public void setPlayer(Player player) {
    this.player = player;
}

public FileInputStream getFis() {
    return fis;
}

public void setFis(FileInputStream fis) {
    this.fis = fis;
}
}

Тогда у меня есть код, который содержит отображение пользовательского интерфейса:

public class UI_Display extends JFrame {

public UI_Display() {
    initialize();
}

public JButton getButtons(String btnName) {
        switch(btnName) {
        case "Pause" :
            return getBtnPause();
        case "Play" : 
            return getBtnPlay();
        case "Stop" :
            return getBtnStop();
        case "Open" : 
            return getBtnEjectOpen();
        case "OpenDir" :
            return getBtnOpenDir();
        case "Prev" :
            return getBtnPrev();
        case "Next" :
            return getBtnNext();
            default : 
                System.out.println("No such button!");
                return null;
        }
    }

    public void setCellRenderer(int newIdex) {
        this.jList_songList.setCellRenderer(new DefaultListCellRenderer() {
            private static final long serialVersionUID = 1676346144422213946L;

            public Component getListCellRendererComponent(JList<?> list, Object value, int index,
                    boolean isSelected, boolean cellHasFocus) {

                super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                Color bg = new Color(245, 0, 0);
                index = newIdex;
                if (list.getModel().getElementAt(index) == value.toString()) {
                    setForeground(bg);

                } else {
                    setForeground(list.getForeground());
                }

                return this;
            }

        });
    }
}

Класс MainControllerImpl знает обо всех 2 других классах:

public class MainControllerImpl implements MainController {

    private UI_Display uiDisplay;
    private UserMainFunctions userMainFuncions;
    private int currentIndex;

    public MainControllerImpl(UI_Display uiDisplay, UserMainFunctions userMainFunctions) {
        this.uiDisplay = uiDisplay;
        this.userMainFuncions = userMainFunctions;
        this.uiDisplay.getSongNameLabel().setFont(new Font("Liquid Crystal", Font.BOLD, 24));
        this.uiDisplay.getSongNameLabel().setForeground(new Color(240, 30, 50));
        this.listenForButtons();
        this.listenForMouseClicks();

    }
    public MainControllerImpl() {

    }
    ActionListener aListener = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {

            JButton sourceBtn = (JButton) e.getSource();
            switch (sourceBtn.getText()) {
            case "Pause":

                break;
            case "Play":
                userMainFuncions.play(userMainFuncions.getCurrentPath());
                setSongDisplay();
                break;
            case "Stop":
                userMainFuncions.stop();
                uiDisplay.getSongNameLabel().setText("Music Stopped!");
                break;
            case "Open":
                userMainFuncions.setCurrentPath(uiDisplay.openFileDialog());
                userMainFuncions.play(userMainFuncions.getCurrentPath());
                setSongDisplay();
                break;
            case "OpenDir":
                List<String> songList = uiDisplay.openDir();
                load_JList(songList);
                break;
            case "Prev":
                decrementList();
                break;
            case "Next":
                incrementList();
                break;
            default:
                break;
            }
        }
    };

    public void load_JList(List<String> songList) {
        if (songList != null) {
            DefaultListModel<String> loadedList = new DefaultListModel<String>();
            for (String s : songList) {
                loadedList.addElement(s);
            }
            uiDisplay.getjList_songList().setModel(loadedList);
            uiDisplay.getjList_songList().setVisibleRowCount(uiDisplay.getjList_songList().getModel().getSize());
            uiDisplay.getjList_songList().setSelectedIndex(0);
            uiDisplay.setCellRenderer(getCurrentIndex());
            userMainFuncions.setCurrentPath(uiDisplay.getjList_songList().getSelectedValue());
            userMainFuncions.play(userMainFuncions.getCurrentPath());
            while(userMainFuncions.getPlayer().isComplete()) {
                System.out.println("asdkjfhsdogfh");
            }

            setSongDisplay();

        }
    }

    public void incrementList() {
        if (getCurrentIndex() < uiDisplay.getjList_songList().getModel().getSize()) {
            setCurrentIndex(getCurrentIndex() + 1);
        }
        if (getCurrentIndex() == uiDisplay.getjList_songList().getModel().getSize()) {
            setCurrentIndex(0);
        }
        userMainFuncions.setCurrentPath(uiDisplay.getjList_songList().getModel().getElementAt(getCurrentIndex()));
        uiDisplay.setCellRenderer(getCurrentIndex());
        userMainFuncions.play(userMainFuncions.getCurrentPath());
        // uiDisplay.getjList_songList().setCellRenderer(renderCells);

    }
    public void decrementList() {
        if (getCurrentIndex() < uiDisplay.getjList_songList().getModel().getSize()&&getCurrentIndex()!=0) {
            setCurrentIndex(getCurrentIndex() - 1);
        }
        else if (getCurrentIndex() == 0) {
            setCurrentIndex(uiDisplay.getjList_songList().getModel().getSize()-1);
        }
        userMainFuncions.setCurrentPath(uiDisplay.getjList_songList().getModel().getElementAt(getCurrentIndex()));
        uiDisplay.setCellRenderer(getCurrentIndex());
        userMainFuncions.play(userMainFuncions.getCurrentPath());
        // uiDisplay.getjList_songList().setCellRenderer(renderCells);

    }

    @Override
    public void listenForButtons() {
        this.uiDisplay.getBtnPause().addActionListener(aListener);
        this.uiDisplay.getBtnPlay().addActionListener(aListener);
        this.uiDisplay.getBtnStop().addActionListener(aListener);
        this.uiDisplay.getBtnOpenDir().addActionListener(aListener);
        this.uiDisplay.getBtnEjectOpen().addActionListener(aListener);
        this.uiDisplay.getBtnPrev().addActionListener(aListener);
        this.uiDisplay.getBtnNext().addActionListener(aListener);
    }

    MouseListener mouseListener = new MouseListener() {

        @Override
        public void mouseReleased(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mousePressed(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseExited(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseEntered(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseClicked(MouseEvent e) {
            if (e.getButton() == MouseEvent.BUTTON1) {
                // System.out.println(uiDisplay.getjList_songList().getSelectedValue());

            }
            if (e.getClickCount() == 2) {
                setCurrentIndex(uiDisplay.getjList_songList().getSelectedIndex());
                uiDisplay.setCellRenderer(getCurrentIndex());
                userMainFuncions.setCurrentPath(uiDisplay.getjList_songList().getSelectedValue());
                userMainFuncions.play(userMainFuncions.getCurrentPath());
                setSongDisplay();
            }

        }
    };

    public void listenForMouseClicks() {
        this.uiDisplay.getjList_songList().addMouseListener(mouseListener);
    }

    private void setSongDisplay() {
        if (userMainFuncions.getCurrentPath() != null) {
            List<String> id3v1tag_List = userMainFuncions.getID3V1TAG(userMainFuncions.getCurrentPath());
            if (id3v1tag_List.size() > 2) {
                uiDisplay.getSongNameLabel().setText(id3v1tag_List.get(2) + " " + id3v1tag_List.get(4));
            } else
                uiDisplay.getSongNameLabel().setText(userMainFuncions.getCurrentPath());
        }
    }

    public int getCurrentIndex() {
        return currentIndex;
    }

    public void setCurrentIndex(int currentIndex) {
        this.currentIndex = currentIndex;
    }


}

Как я могу запустить такой метод, как "increment" внутри этого потока (в цикле while), не прерывая SRP?

Большое спасибо, ребята!

1 Ответ

0 голосов
/ 08 января 2019

Вместо того чтобы завершить проверку в том же потоке, вы можете вернуть логическое значение после завершения и захватить его в будущем. Затем Future.get будет ждать, пока воспроизводящая нить не вернется после завершения песни.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...