最近两天,我第一次尝试用Java写一个GUI程序,写了个LRC文件编辑器。简单地说,就是先导入歌,然后导入歌词(顺序可以颠倒,导入歌词可以用复制粘贴代替),然后一边播放歌曲,一边添加时间标签。然后根据你输入的歌手名、专辑名等信息自动生成标准格式的LRC文件。两个菜单中的项目快捷键已经在菜单中标明。主界面长这个样子(拿绝对定位写的,有点儿丑,不支持reSize):

最终能生成这样的文件:

只供学习交流之用,希望大家能别嫌弃我比较菜。编译代码之前别忘了去官网下载Java Media Framework(地址:Java Archive Downloads - JMF),然后把5个jar包导入到工程里才能用(至少需要SE 8的版本)。有的实在不知道怎么改的Bug已经在源代码的文档注释中写清了。如果还有其他Bug希望大家能告诉我哈~ 完整代码如下:

// Coding start here
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;import javax.media.ControllerEvent;
import javax.media.ControllerListener;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.Player;
import javax.media.PrefetchCompleteEvent;
import javax.media.Time;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.text.BadLocationException;/*** 本作品原创,可用于编辑LRC歌词,实现了滑块条的同步,时间处理以及音频处理。* 该程序实质是JMF框架的一个实例,用awt和Swing组件配套完成。* * 【BUG列表】(实在无法解决的)* 1、保存LRC文件时,只有用户输入的名称带有“.lrc”才能判断是否与文件重名。这个问题待处理;* 2、滑块条必须快速滑动才能使用,或许是JMF框架的缺点,或许是我的事件处理方式不当;* 3、导入一个新的MP3时,第一次按下“Pause”按钮可能会使歌曲进度错位两秒,真是让人头疼。* 所以制作歌词的时候还是别暂停了。如果只是想听歌的话随便。。。这个问题待处理;* 4、控制系统音量的部分实在不会弄,不像C#那么容易,干脆直接把音量滑块条删了;* 5、显示版权窗口的时候可能不会居中显示。* * 在进阶的路上,欢迎各位大神指正。* @author 赵利昂* @version 20180222* @since 20180219*/
public class lrcEditor extends JFrame
{private JPanel contentPane;private JSlider slider;private String filepath = "\\standby:";private String filename = "\\standby:";private boolean isPlaying = false;private boolean isPaused = false;private boolean fileAccepted = false;private int offsetDirection = -1;  // 1表示offset为提前值(正数),0表示延后(负数),-1表示不使用offsetprivate int currentRow = 0;  // 当前光标所在行数private Player player;private double audioLength;  // 歌曲总长度,单位是秒,但是会有小数private Timer t = null;  // 控制滑块条的进度与歌曲同步private JTextField artists;private JTextField title;private JTextField album;private JTextField madeBy;private JTextField offset;/*** 应用程序初始化*/public static void main(String[] args){EventQueue.invokeLater(() -> {try {lrcEditor frame = new lrcEditor();frame.setVisible(true);frame.setLocationRelativeTo(null);} catch (Exception e) {e.printStackTrace();}});}/*** 新建一个画布*/@SuppressWarnings("unchecked")public lrcEditor(){addWindowListener(new WindowAdapter(){@Overridepublic void windowClosing(WindowEvent e){JOptionPane.showMessageDialog(null, "Any questions or suggestions, please contact\n"+ "Hippo by 652961752@163.com to report.\nGood day!","Goodbye!", JOptionPane.INFORMATION_MESSAGE);}});setResizable(false);setTitle("HIPPO Lyrics Editor - 2018.02.22");setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setBounds(100, 100, 1080, 715);contentPane = new JPanel();contentPane.setBackground(SystemColor.desktop);contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));setContentPane(contentPane);contentPane.setLayout(null);JLabel lblNewLabel = new JLabel("Additional choices");lblNewLabel.setOpaque(true);lblNewLabel.setBorder(new LineBorder(new Color(0, 0, 0), 2));lblNewLabel.setBackground(Color.BLACK);lblNewLabel.setFont(new Font("微软雅黑", Font.BOLD, 17));lblNewLabel.setForeground(Color.CYAN);lblNewLabel.setBounds(788, 49, 161, 27);contentPane.add(lblNewLabel);JLabel stateLabel = new JLabel(" Lyrics editor standby.");stateLabel.setBorder(new LineBorder(Color.WHITE, 3));stateLabel.setOpaque(true);stateLabel.setForeground(Color.GREEN);stateLabel.setBackground(Color.BLACK);stateLabel.setFont(new Font("Calibri", Font.PLAIN, 19));stateLabel.setBounds(4, 6, 1066, 32);contentPane.add(stateLabel);JLabel currentLabel = new JLabel("00:00.00");currentLabel.setFont(new Font("Calibri", Font.PLAIN, 16));currentLabel.setForeground(Color.YELLOW);currentLabel.setBounds(534, 106, 76, 20);contentPane.add(currentLabel);JLabel lengthLabel = new JLabel("00:00.00");lengthLabel.setForeground(Color.YELLOW);lengthLabel.setFont(new Font("Calibri", Font.PLAIN, 16));lengthLabel.setBounds(605, 106, 64, 20);contentPane.add(lengthLabel);JTextArea textArea = new JTextArea();textArea.setFont(new Font("宋体", Font.PLAIN, 16));textArea.setBackground(new Color(204, 255, 255));textArea.setBounds(13, 130, 657, 519);/*textArea.addCaretListener(new CaretListener(){public void caretUpdate(CaretEvent e){try {currentRow = textArea.getLineOfOffset(e.getDot());} catch (Exception ex) {ex.printStackTrace();}}});*/contentPane.add(textArea);JScrollPane scrollPane = new JScrollPane(textArea);scrollPane.setBounds(10, 130, 657, 519);contentPane.add(scrollPane);JMenuBar menuBar = new JMenuBar();menuBar.setBorderPainted(false);menuBar.setBackground(SystemColor.desktop);menuBar.setOpaque(true);menuBar.setForeground(new Color(0, 0, 0));setJMenuBar(menuBar);JMenu mnFiles = new JMenu("Files");mnFiles.setForeground(Color.WHITE);mnFiles.setBackground(SystemColor.desktop);mnFiles.setFont(new Font("微软雅黑", Font.PLAIN, 16));mnFiles.setMnemonic('F');menuBar.add(mnFiles);JMenuItem itemSelectAudio = new JMenuItem("Select an audio");itemSelectAudio.setAccelerator(KeyStroke.getKeyStroke("ctrl M"));itemSelectAudio.setForeground(Color.WHITE);itemSelectAudio.setBackground(Color.BLACK);itemSelectAudio.addActionListener(event ->{JFileChooser chooser = new JFileChooser();chooser.setCurrentDirectory(new File("."));chooser.removeChoosableFileFilter(chooser.getAcceptAllFileFilter());chooser.setFileFilter(new FileNameExtensionFilter("Available audio files(*.mp3 | wav | mid)", "mp3", "wav", "mid"));int result = chooser.showOpenDialog(null);if(result == JFileChooser.APPROVE_OPTION){filename = chooser.getSelectedFile().getName();filepath = chooser.getSelectedFile().getAbsolutePath();if(!new File(filepath).exists()){JOptionPane.showMessageDialog(this, "The file does not exist!", "Error occurred", JOptionPane.OK_OPTION);filename = "\\standby:";filepath = "\\standby:";fileAccepted = false;stateLabel.setText(" Lyrics editor standby.");}else if(!(filename.endsWith(".mp3") || filename.endsWith(".wav") || filename.endsWith(".mid"))){JOptionPane.showMessageDialog(this, "Unacceptable extension!", "Error occurred", JOptionPane.OK_OPTION);filename = "\\standby:";filepath = "\\standby:";fileAccepted = false;stateLabel.setText(" Lyrics editor standby.");}else{fileAccepted = true;stateLabel.setText(" Ready to process: " + filename);currentRow = 0;}}if(player != null){t.stop();player.stop();slider.setValue(0);}});itemSelectAudio.setFont(new Font("微软雅黑", Font.PLAIN, 14));mnFiles.add(itemSelectAudio);JMenuItem itemImportLyrics = new JMenuItem("Import lyrics");itemImportLyrics.setAccelerator(KeyStroke.getKeyStroke("ctrl I"));itemImportLyrics.addActionListener(event ->{JFileChooser chooser = new JFileChooser();String lrcFilename = "";String lrcFilepath = "";chooser.setCurrentDirectory(new File("."));chooser.removeChoosableFileFilter(chooser.getAcceptAllFileFilter());chooser.setFileFilter(new FileNameExtensionFilter("Available raw lyrics files(*.txt)", "txt"));int result = chooser.showOpenDialog(null);if(result == JFileChooser.APPROVE_OPTION){lrcFilename = chooser.getSelectedFile().getName();lrcFilepath = chooser.getSelectedFile().getAbsolutePath();if(!new File(lrcFilepath).exists()){JOptionPane.showMessageDialog(this, "The file does not exist!", "Error occurred", JOptionPane.OK_OPTION);stateLabel.setText(" Lyrics editor standby.");}else if(!(lrcFilename.endsWith(".txt"))){JOptionPane.showMessageDialog(this, "Unacceptable extension!", "Error occurred", JOptionPane.OK_OPTION);stateLabel.setText(" Lyrics editor standby.");}else{try(FileReader filereader = new FileReader(new File(lrcFilepath));BufferedReader bufferreader = new BufferedReader(filereader)) {String newline;while ((newline = bufferreader.readLine()) != null)textArea.append(newline + "\r\n");textArea.append("\r\n");} catch(IOException e) {e.printStackTrace();}stateLabel.setText(" Lyric file successfully imported: " + lrcFilename);currentRow = 0;}}});itemImportLyrics.setBackground(Color.BLACK);itemImportLyrics.setForeground(Color.WHITE);itemImportLyrics.setFont(new Font("微软雅黑", Font.PLAIN, 14));mnFiles.add(itemImportLyrics);JMenuItem itemExportLrcFiles = new JMenuItem("Export LRC files");itemExportLrcFiles.setAccelerator(KeyStroke.getKeyStroke("ctrl O"));itemExportLrcFiles.addActionListener(event ->{JFileChooser chooser = new JFileChooser();File saveToFile = null;String saveToFileName = ".";chooser.setCurrentDirectory(new File("."));chooser.removeChoosableFileFilter(chooser.getAcceptAllFileFilter());chooser.setFileFilter(new FileNameExtensionFilter("Standard lyrics files(*.lrc)", "lrc"));int result = chooser.showSaveDialog(null);if(result == JFileChooser.APPROVE_OPTION){saveToFile = chooser.getSelectedFile();saveToFileName = chooser.getName(saveToFile);if(saveToFileName == null || saveToFileName.trim().equals("") || !isLegal(saveToFileName))JOptionPane.showMessageDialog(null, "Illegal file name detected.", "Error occurred", JOptionPane.OK_OPTION);else if(saveToFile.isFile())saveToFileName = saveToFile.getName();elsesaveToFile = chooser.getCurrentDirectory();String path = saveToFile.getPath() + File.separator + saveToFileName;if(!saveToFileName.endsWith(".lrc"))  // 判断用户输入的文件名是否包含lrc扩展名path += ".lrc";saveToFile = new File(path);int i = -2;if(saveToFile.exists())i = JOptionPane.showConfirmDialog(null, "A namesake detected. Do you want to overwrite?", "Error occured", JOptionPane.YES_NO_CANCEL_OPTION);if(i == JOptionPane.YES_OPTION || !saveToFile.exists()){try(OutputStreamWriter hippo = new OutputStreamWriter(new FileOutputStream(saveToFile))){hippo.write("[ar:" + artists.getText() + "]\r\n[ti:" + title.getText() + "]\r\n[al:" + album.getText()+ "]\r\n[by:" + madeBy.getText() + "]\r\n");if(offsetDirection != -1 && !offset.getText().equals(""))  // 如果使用offset标签{hippo.write("[offset:");if(offsetDirection == 0)hippo.write("-");hippo.write(offset.getText() + "]\r\n");}for(String line : textArea.getText().split("\n"))hippo.write("\r\n" + line);hippo.write("\r\n");} catch(IOException e1) {JOptionPane.showMessageDialog(null, "An error occurred while saving.", "Error occurred", JOptionPane.OK_OPTION);}}}});itemExportLrcFiles.setBackground(Color.BLACK);itemExportLrcFiles.setForeground(Color.WHITE);itemExportLrcFiles.setFont(new Font("微软雅黑", Font.PLAIN, 14));mnFiles.add(itemExportLrcFiles);mnFiles.addSeparator();JMenuItem itemExit = new JMenuItem("Exit");itemExit.setAccelerator(KeyStroke.getKeyStroke("ctrl alt K"));itemExit.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){System.exit(0);  // 直接关闭,不显示常规关闭时的对话框}});itemExit.setBackground(Color.BLACK);itemExit.setForeground(new Color(255, 165, 0));itemExit.setFont(new Font("微软雅黑", Font.PLAIN, 14));mnFiles.add(itemExit);JMenu mnOthers = new JMenu("Others");mnOthers.setForeground(Color.WHITE);mnOthers.setBackground(SystemColor.desktop);mnOthers.setFont(new Font("微软雅黑", Font.PLAIN, 16));mnOthers.setMnemonic('O');menuBar.add(mnOthers);JMenuItem mntmHelp = new JMenuItem("Help");mntmHelp.setAccelerator(KeyStroke.getKeyStroke("ctrl H"));mntmHelp.addActionListener(event ->{JOptionPane.showMessageDialog(null, "The program is designed to help produce LRC files.\n"+ "We recommend you to tag all the lyrics without pauses.\n"+ "You can do it without instructions. Good luck!","Help", JOptionPane.INFORMATION_MESSAGE);});mntmHelp.setBackground(Color.BLACK);mntmHelp.setForeground(Color.WHITE);mntmHelp.setFont(new Font("微软雅黑", Font.PLAIN, 14));mnOthers.add(mntmHelp);mnOthers.addSeparator();JMenuItem itemNotice = new JMenuItem("Copyright Notice");itemNotice.setAccelerator(KeyStroke.getKeyStroke("ctrl C"));itemNotice.addActionListener(event ->{AboutDialog about = new AboutDialog(this);about.setVisible(true);});itemNotice.setBackground(Color.BLACK);itemNotice.setForeground(Color.WHITE);itemNotice.setFont(new Font("微软雅黑", Font.PLAIN, 14));mnOthers.add(itemNotice);/** 控制“播放”按钮*/JButton playBtn = new JButton("Play");playBtn.setFont(new Font("Calibri", Font.PLAIN, 18));playBtn.addActionListener(event ->{if(player != null){if(isPaused)isPaused = false;else{processPlayer();setAudioPath();}}elsesetAudioPath();isPlaying = true;player.realize();player.prefetch();player.start();player.addControllerListener(new ControllerListener(){public void controllerUpdate(ControllerEvent controllerevent){if(controllerevent instanceof PrefetchCompleteEvent){audioLength = player.getDuration().getSeconds();lengthLabel.setText(getFormatLength());}}});stateLabel.setText(" Playing: " + filename);t = new Timer(87, e ->{currentLabel.setText(getCurrentFormatLength());int currentValue = (int) (player.getMediaTime().getSeconds() * 1000.0 / audioLength);slider.setValue(currentValue);if(slider.getValue() >= 1000){stateLabel.setText(" Playing accomplished: " + filename);currentLabel.setText("00:00.00");t.stop();slider.setValue(0);}});t.start();});playBtn.setBounds(247, 44, 97, 35);contentPane.add(playBtn);/** 控制“暂停”按钮*/JButton pauseBtn = new JButton("Pause");pauseBtn.addActionListener(event ->{if(player != null){stateLabel.setText(" Paused: " + filename);isPaused = true;player.stop();t.stop();}});pauseBtn.setFont(new Font("Calibri", Font.PLAIN, 18));pauseBtn.setBounds(140, 44, 97, 35);contentPane.add(pauseBtn);/** 控制“停止播放”按钮*/JButton stopBtn = new JButton("Stop");stopBtn.addActionListener(event ->{if (player != null){stateLabel.setText(" Stopped playing: " + filename);currentLabel.setText("00:00.00");player.stop();player.setMediaTime(new Time(0));t.stop();slider.setValue(0);}currentRow = 0;});stopBtn.setFont(new Font("Calibri", Font.PLAIN, 18));stopBtn.setBounds(33, 44, 97, 35);contentPane.add(stopBtn);slider = new JSlider();slider.addMouseListener(new MouseAdapter(){@Overridepublic void mouseReleased(MouseEvent e){double sliderValue = (double) slider.getValue();double newLength = audioLength * sliderValue / 1000.0;player.setMediaTime(new Time(newLength));}});slider.setMaximum(1000);slider.setPaintLabels(true);slider.setPaintTicks(true);slider.setValue(0);slider.setBackground(Color.BLACK);slider.setBounds(10, 86, 657, 23);contentPane.add(slider);JPanel panel = new JPanel();panel.setForeground(Color.WHITE);panel.setBackground(Color.BLACK);panel.setBorder(new LineBorder(new Color(192, 192, 192), 3, true));panel.setBounds(682, 61, 379, 588);contentPane.add(panel);panel.setLayout(null);madeBy = new JTextField();madeBy.setFont(new Font("Calibri", Font.PLAIN, 14));madeBy.setColumns(10);madeBy.setBounds(108, 150, 249, 26);panel.add(madeBy);offset = new JTextField();offset.setFont(new Font("Calibri", Font.PLAIN, 14));offset.setText("0");offset.setColumns(10);offset.setBounds(108, 189, 249, 26);panel.add(offset);album = new JTextField();album.setFont(new Font("Calibri", Font.PLAIN, 14));album.setColumns(10);album.setBounds(108, 111, 249, 26);panel.add(album);title = new JTextField();title.setFont(new Font("Calibri", Font.PLAIN, 14));title.setColumns(10);title.setBounds(108, 72, 249, 26);panel.add(title);artists = new JTextField();artists.setFont(new Font("Calibri", Font.PLAIN, 14));artists.setBounds(108, 33, 249, 26);panel.add(artists);artists.setColumns(10);JLabel lblNewLabel_1 = new JLabel("Artists: ");lblNewLabel_1.setFont(new Font("Calibri", Font.PLAIN, 18));lblNewLabel_1.setBounds(23, 31, 75, 30);lblNewLabel_1.setForeground(Color.WHITE);lblNewLabel_1.setBackground(Color.BLACK);lblNewLabel_1.setOpaque(true);panel.add(lblNewLabel_1);JLabel lblTitle = new JLabel("Title: ");lblTitle.setOpaque(true);lblTitle.setForeground(Color.WHITE);lblTitle.setFont(new Font("Calibri", Font.PLAIN, 18));lblTitle.setBackground(Color.BLACK);lblTitle.setBounds(23, 70, 75, 30);panel.add(lblTitle);JLabel lblAlbum = new JLabel("Album: ");lblAlbum.setOpaque(true);lblAlbum.setForeground(Color.WHITE);lblAlbum.setFont(new Font("Calibri", Font.PLAIN, 18));lblAlbum.setBackground(Color.BLACK);lblAlbum.setBounds(23, 109, 75, 30);panel.add(lblAlbum);JLabel lblMadeBy = new JLabel("Made by: ");lblMadeBy.setOpaque(true);lblMadeBy.setForeground(Color.WHITE);lblMadeBy.setFont(new Font("Calibri", Font.PLAIN, 18));lblMadeBy.setBackground(Color.BLACK);lblMadeBy.setBounds(23, 148, 75, 30);panel.add(lblMadeBy);JLabel lblOffset = new JLabel("Offset: ");lblOffset.setOpaque(true);lblOffset.setForeground(Color.WHITE);lblOffset.setFont(new Font("Calibri", Font.PLAIN, 18));lblOffset.setBackground(Color.BLACK);lblOffset.setBounds(23, 187, 75, 30);panel.add(lblOffset);JLabel lblOffsetType = new JLabel("Offset type: ");lblOffsetType.setOpaque(true);lblOffsetType.setForeground(Color.WHITE);lblOffsetType.setFont(new Font("Calibri", Font.PLAIN, 18));lblOffsetType.setBackground(Color.BLACK);lblOffsetType.setBounds(23, 226, 91, 30);panel.add(lblOffsetType);@SuppressWarnings("rawtypes")JComboBox comboBox = new JComboBox();comboBox.setFont(new Font("Calibri", Font.PLAIN, 14));comboBox.addActionListener(event ->{String currentBox = comboBox.getSelectedItem().toString();switch(currentBox){case "Cancel offset":offset.setEnabled(false);offset.setText("0");offsetDirection = -1;break;case "Ahead of time":offset.setEnabled(true);offset.setText("");offsetDirection = 1;break;case "Lag of time":offset.setEnabled(true);offset.setText("");offsetDirection = 0;}});comboBox.setBounds(128, 228, 229, 26);comboBox.addItem("Cancel offset");comboBox.addItem("Ahead of time");comboBox.addItem("Lag of time");panel.add(comboBox);JButton btnAddArtistsAnd = new JButton("Add artists, title and author in the front");btnAddArtistsAnd.addActionListener(event ->{textArea.insert("[-00:00.10]" + artists.getText() + " - " + title.getText() + "\n[-00:00.07]\n[-00:00.04]Made by "+ madeBy.getText() + "\n[-00:00.01]\n", 0);});btnAddArtistsAnd.setFont(new Font("Calibri", Font.PLAIN, 18));btnAddArtistsAnd.setBounds(23, 272, 334, 35);panel.add(btnAddArtistsAnd);JButton btnAppendEndIcon = new JButton("Append an end line in the last milisecond");btnAppendEndIcon.addActionListener(event ->{textArea.append("[" + getFormatLength() + "]--- This is the end of the lyric. ---\n");});btnAppendEndIcon.setFont(new Font("Calibri", Font.PLAIN, 18));btnAppendEndIcon.setBounds(23, 321, 334, 35);panel.add(btnAppendEndIcon);JButton btnRestoreAllChoices = new JButton("Restore all choices to default settings");btnRestoreAllChoices.addActionListener(event ->{int choice = JOptionPane.showConfirmDialog(null, "Start restoring?", "Confirmation required", JOptionPane.YES_NO_CANCEL_OPTION);if(choice == JOptionPane.YES_OPTION){artists.setText("");title.setText("");album.setText("");madeBy.setText("");offset.setText("0");comboBox.setSelectedItem("Cancel offset");offsetDirection = -1;JOptionPane.showMessageDialog(null, "Done.", "From restore process", JOptionPane.OK_CANCEL_OPTION);}});btnRestoreAllChoices.setFont(new Font("Calibri", Font.PLAIN, 18));btnRestoreAllChoices.setBounds(23, 370, 334, 35);panel.add(btnRestoreAllChoices);JTextArea txtrWarningaddAnd = new JTextArea();txtrWarningaddAnd.setFont(new Font("Calibri", Font.PLAIN, 18));txtrWarningaddAnd.setBackground(new Color(0, 0, 0));txtrWarningaddAnd.setEditable(false);txtrWarningaddAnd.setForeground(new Color(255, 255, 102));txtrWarningaddAnd.setLineWrap(true);txtrWarningaddAnd.setText("[Warning] \"Add\" and \"Append\" buttons "+ "should only be used after you have tagged the lyrics. \r\n"+ "Once you started tagging, do not change the \r\nline counts of the lyric. "+ "The usage of \"offset\" is not recommended due to compatibility.\r\n     "+ "                                                               --- Hippo");txtrWarningaddAnd.setBounds(20, 419, 345, 160);panel.add(txtrWarningaddAnd);JButton addTimeBtn = new JButton("Add time tags");addTimeBtn.addActionListener(event ->{String currentTimeTag = String.format("[%s]", getCurrentFormatLength());int position = 0;int lineCount = textArea.getLineCount();try {position = textArea.getLineStartOffset(currentRow++);if(currentRow >= lineCount)textArea.append("\n");} catch (BadLocationException e1) {e1.printStackTrace();}textArea.setCaretPosition(position);textArea.insert(currentTimeTag, position);});addTimeBtn.setFont(new Font("Calibri", Font.PLAIN, 18));addTimeBtn.setBounds(381, 44, 248, 35);contentPane.add(addTimeBtn);JLabel label = new JLabel("/");label.setForeground(Color.YELLOW);label.setFont(new Font("Calibri", Font.PLAIN, 16));label.setBounds(595, 105, 14, 20);contentPane.add(label);}/*** 检查保存的文件名是否合法* @param s 要被检查的字符串* @return 是否合法的标志(true/false)*/public static boolean isLegal(String s){if(s.contains("/") || s.contains("\\") || s.contains(":") || s.contains("\"") || s.contains("|") || s.contains("*")|| s.contains("<") || s.contains(">")  || s.contains("\'") || s.contains("?") || s.contains(";") || s.contains("="))return false;return true;}/*** 在播放之前的预处理工作*/public void processPlayer(){if(!fileAccepted){JOptionPane.showMessageDialog(this, "You haven't choosen a file!", "Error occurred", JOptionPane.OK_OPTION);return;}if(isPlaying){isPlaying = false;player.stop();player.setMediaTime(new Time(0));}}/*** 将播放路径添加至Player*/public void setAudioPath(){try {player = Manager.createPlayer(new MediaLocator("file:" + filepath));} catch(Exception e) {System.out.println(e.getMessage());}}/*** 处理音乐文件总长度的标签* @return 歌曲的总长度,格式为mm:ss.nn(n为毫秒数)*/public String getFormatLength(){StringBuilder sb = new StringBuilder();int minutes = (int) audioLength / 60;if(minutes < 10)sb.append("0");sb.append(minutes);sb.append(":");int seconds = (int) audioLength % 60;if(seconds < 10)sb.append("0");sb.append(seconds);sb.append(".");sb.append(String.format("%02.0f", (audioLength - (int) audioLength) * 100.0));return sb.toString();}/*** 处理音乐文件当前位置的标签* @return 当前音乐播放的进度,格式为mm:ss.nn(n为毫秒数)*/public String getCurrentFormatLength(){StringBuilder sb = new StringBuilder();double currentSeconds = player.getMediaTime().getSeconds();int minutes = (int) currentSeconds / 60;if(minutes < 10)sb.append("0");sb.append(minutes);sb.append(":");int seconds = (int) currentSeconds % 60;if(seconds < 10)sb.append("0");sb.append(seconds);sb.append(".");sb.append(String.format("%02.0f", (currentSeconds - (int) currentSeconds) * 100.0));return sb.toString();}
}/*** 版权声明窗口(居中显示可能会存在问题)* @author 赵利昂* @since 20180222*/
class AboutDialog extends JDialog
{public AboutDialog(JFrame owner){super(owner, "Copyright Notice", true);add(new JLabel("<html><h2><font color=\"blue\"><b><i> HIPPO</i>(C) Lyrics Editor </b></h2></color>"+ "<p> All rights reserved.</html>"),BorderLayout.CENTER);JButton ok = new JButton("I got it.");ok.addActionListener(event -> setVisible(false));JPanel panel = new JPanel();panel.add(ok);add(panel, BorderLayout.SOUTH);setLocationRelativeTo(null);pack();}
}

个人对Java的GUI编程不是特别感兴趣。。C#还是比较喜欢的。往后就开始学习JavaEE的内容了:)

在进阶的路上,欢迎各位大神指正。

用Java写LRC制作器,实现音乐播放和滑块条进度同步相关推荐

  1. Android制作简易的音乐播放器和视频播放器

    文章目录 制作简易的音乐播放器和视频播放器 播放多媒体文件 播放音频 MediaPlayer的工作流程 项目示例 播放视频 项目示例 制作简易的音乐播放器和视频播放器 播放多媒体文件 Android在 ...

  2. html音频从10秒播放至30秒,基于Arduino制作SD卡音乐播放器

    一.项目介绍 前面用ATtiny85制作SD卡音乐播放器,本次主要利用Arduino UNO 和SD卡制作音乐播放器.这个播放器不需要添加多余的模块,只需要SD读卡器和Arduino UNO开发板就可 ...

  3. html制作在线视频音乐播放器,用html5制作音乐播放器,这3款就足够了!

    用HTML5结合Jquery做一个简易版的音乐播放器 代码展示: 三生草 var sum = 1; function ssss(a) { var s = document.getElementById ...

  4. html通过自适应制作手机端音乐播放器

    html通过自适应制作手机端音乐播放器 实现效果: 实现思路: 1.布局: (1).将手机的宽度进行10等分  为10rem (2).通过rem定义各个元素的宽高.间距.字体大小 (3).通过CSS3 ...

  5. JAVA毕业设计vue开发一个简单音乐播放器计算机源码+lw文档+系统+调试部署+数据库

    JAVA毕业设计vue开发一个简单音乐播放器计算机源码+lw文档+系统+调试部署+数据库 JAVA毕业设计vue开发一个简单音乐播放器计算机源码+lw文档+系统+调试部署+数据库 本源码技术栈: 项目 ...

  6. 【毕业设计】28-基于单片机的音乐播放器简易音乐播放器设计(原理图+源代码+仿真工程+答辩PPT+答辩论文)

    typora-root-url: ./ [毕业设计]28-基于单片机的音乐播放器简易音乐播放器设计(原理图+源代码+仿真工程+答辩PPT+答辩论文) 文章目录 typora-root-url: ./ ...

  7. php 在线调用音乐播放器,宅音乐播放器,HTML5网页播放器,带后台管理及API调用,使用thinkphp编写...

    宅音乐播放器 宅音乐播放器,HTML5网页播放器,集成后台管理及API调用,目前正在开发中,敬请关注 技术栈 后端:thinkphp 5.1 前端:layui 数据库:mysql 演示 整合依赖安装包 ...

  8. java制作mp3_利用java制作简单的音乐播放器

    本文主要是用到java中的swing技术,以及JMFjar中的API,为大家分享了java音乐播放器的具体实现代码,供大家参考,具体内容如下 备注:需要用JDK1.8才能播放音乐MP3 package ...

  9. java电脑桌面网易云界面,Javafx音乐播放器

    Javafx音乐播放器 介绍 这是款由纯java语言开发的在线音乐播放器,当然也支持播放本地的音乐,在本地音乐模块主要采用目前java最主流的音频标记库Jaudiotagger,可解析MP3文件头信息 ...

最新文章

  1. p6安装后怎么连接oracle的数据库,p6-oraclexe数据库连接不上处理方法内部版20151012.doc...
  2. java - 分页类
  3. CreateProcess failed: The system cannot find the file specified.
  4. 用python的matplotlib画标准正态曲线
  5. Apache Camel 2.19发布–新增功能
  6. 条件运算符(?:)和 $替代string.Format()
  7. layui导航栏页面滚动固定_帮你搞定长滚动网页的设计!这5种设计策略需谨记!...
  8. python支持向量机 股票_小蛇学python(4)利用SVM预测股票涨跌
  9. Mysql数据库更新操作导致死锁问题
  10. 学成在线首页——静态页面(html+css)素材链接放在文章结尾了
  11. SpringBoot验证码
  12. JavaScript中的attachEvent和addEventListener
  13. 使用FileZilla删除乱码名称文件
  14. app提交到iTunes失败
  15. 开篇鸿蒙谁为情种,曹雪芹  红楼梦引子    开辟鸿蒙,谁为情种?都只为风月情浓。 这句话什么意思 只要这句话的解释...
  16. js 根据链接下载 excel 文件
  17. AWS 云产品和云计算基础知识详解
  18. 生态 | 解析行业发展前沿 聚焦应用迁移难题,人大金仓受邀参加2020数据技术嘉年华...
  19. 鼠标滑过图片抖动晃动效果(css/Shake)
  20. rhel8安装libpcap-devel包

热门文章

  1. [时间序列分析]原创 - 海岛算法
  2. C语言知识点 -- 动态内存管理、文件操作
  3. debian 10 修改网卡名称为eth0
  4. android listview qq,Android中使用listview实现qq/微信好友列表
  5. 5728系统刷机步骤
  6. KeyError: ‘passes columns are not ALL present dataframe‘
  7. 股票量化分析工具QTYX使用攻略——小市值轮动选股策略(更新2.5.9)
  8. python十进制转换_Python 进制转换
  9. jquery一个div怎么获得焦点和失去焦点?
  10. Python中几个非常有趣的模块