import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JMenuBar; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.Box; import javax.swing.BorderFactory; import java.awt.Graphics; import java.awt.FontMetrics; import java.awt.Dimension; import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.util.List; import java.util.ArrayList; class PostWindow extends JFrame implements ActionListener { private Post post; // - -%- - private PostComponent postDisplay; private RepliesComponent repliesDisplay; // ---%-@-%--- public void setPost(Post post) { if (post == null) { post = new Post(); post.text = "This is a sample post."; post.authorId = "snowyfox@biskuteri.cafe"; post.authorName = "snowyfox"; post.date = "0712hrs, 17 July"; post.visibility = PostVisibility.MENTIONED; post.postId = "000000000"; post.boosted = false; post.favourited = true; } this.post = post; postDisplay.setAuthor(post.authorName); postDisplay.setTime(post.date); postDisplay.setText(post.text); // And, reply display too, later. } // - -%- - public void actionPerformed(ActionEvent eA) { Object src = eA.getSource(); if (!(src instanceof JMenuItem)) return; String text = ((JMenuItem)src).getText(); if (text.equals("Post")) { setContentPane(postDisplay); revalidate(); /* * (知) Setting a content pane in itself doesn't * do anything to the content pane. Validation * of the validate root does. Which happens on * window realisation, or by manual call. */ } else if (text.equals("Replies")) { setContentPane(repliesDisplay); revalidate(); } } // ---%-@-%--- PostWindow() { getContentPane().setPreferredSize(new Dimension(360, 270)); pack(); setDefaultCloseOperation(DISPOSE_ON_CLOSE); setLocationByPlatform(true); postDisplay = new PostComponent(); repliesDisplay = new RepliesComponent(); { List authors = new ArrayList<>(); List texts = new ArrayList<>(); authors.add("Black tea"); authors.add("Green tea"); authors.add("White tea"); texts.add("Rich.."); texts.add("Clean!"); texts.add("Myu.."); repliesDisplay.setReplies(authors, texts); } setPost(null); JMenu postMenu = new JMenu("Post"); addToMenu(postMenu, "Favourite"); addToMenu(postMenu, "Reply"); JMenu displayMenu = new JMenu("Display"); addToMenu(displayMenu, "Post"); addToMenu(displayMenu, "Replies"); JMenuBar menuBar = new JMenuBar(); menuBar.add(postMenu); menuBar.add(displayMenu); setJMenuBar(menuBar); setContentPane(postDisplay); } private void addToMenu(JMenu menu, String text) { JMenuItem item = new JMenuItem(text); item.addActionListener(this); menu.add(item); } } class PostComponent extends JPanel { private String author, time, text; // ---%-@-%--- public void setAuthor(String author) { assert author != null; this.author = author; } public void setTime(String time) { assert time != null; this.time = time; } public void setText(String text) { assert text != null; this.text = text; } // - -%- - protected void paintComponent(Graphics g) { int lineHeight = 20; FontMetrics met = g.getFontMetrics(); g.drawString(author, 0, lineHeight); int t1 = getWidth() - met.stringWidth(time); g.drawString(time, t1, lineHeight); int t2 = lineHeight; for (String line: split(text, 48)) { t2 += lineHeight; g.drawString(line, 0, t2); } } private List split(String string, int lineLength) { List returnee = new ArrayList<>(); int start, max = string.length(); for (start = 0; start < max; start += lineLength) { returnee.add(string.substring( start, Math.min(max, start + lineLength) )); } return returnee; } // ---%-@-%--- PostComponent() { author = time = text = ""; setFont(getFont().deriveFont(14f)); } } class RepliesComponent extends JPanel { private List authors, texts; private JButton prevPage, nextPage; private JLabel pageLabel; private ReplyPreviewComponent[] previews; // ---%-@-%--- public void setReplies(List authors, List texts) { assert authors != null; assert texts != null; assert authors.size() == texts.size(); this.authors.clear(); this.authors.addAll(authors); this.texts.clear(); this.texts.addAll(texts); displayPage(1); int currentPage = authors.isEmpty() ? 0 : 1; int pages = (7 + authors.size()) / 8; // (0 + 7) / 8 = 0 // (1 + 7) / 8 = 1 // (8 + 7) / 8 = 1 // (9 + 7) / 8 = 2 // (32 + 7) / 8 = 4 pageLabel.setText(currentPage + "/" + pages); } // - -%- - private void displayPage(int pageNumber) { int oS = (pageNumber - 1) * 8; if (oS >= authors.size()) return; // (悪) Quietly fail? int oE = Math.min(oS + 8, authors.size()); List authors = this.authors.subList(oS, oE); List texts = this.texts.subList(oS, oE); int l = oE - oS; for (int o = 0; o < 8; ++o) { ReplyPreviewComponent preview = previews[o]; if (o >= l) // That doesn't seem right.. { preview.setVisible(false); } else { preview.setAuthor(authors.get(oS + o)); preview.setText(texts.get(oS + o)); preview.setVisible(true); } } } // ---%-@-%--- RepliesComponent() { authors = new ArrayList<>(); texts = new ArrayList<>(); prevPage = new JButton("<"); nextPage = new JButton(">"); prevPage.setEnabled(false); nextPage.setEnabled(false); pageLabel = new JLabel("0 / 0"); Box bottom = Box.createHorizontalBox(); bottom.add(Box.createGlue()); bottom.add(prevPage); bottom.add(Box.createHorizontalStrut(8)); bottom.add(pageLabel); bottom.add(Box.createHorizontalStrut(8)); bottom.add(nextPage); JPanel centre = new JPanel(); centre.setOpaque(false); centre.setLayout(new GridLayout(0, 1, 0, 2)); previews = new ReplyPreviewComponent[8]; for (int o = 0; o < previews.length; ++o) { previews[o] = new ReplyPreviewComponent(); previews[o].setVisible(false); centre.add(previews[o]); } setLayout(new BorderLayout(0, 8)); add(centre, BorderLayout.CENTER); add(bottom, BorderLayout.SOUTH); setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8)); } } class ReplyPreviewComponent extends JButton { private String author; private String text; // ---%-@-%--- @Override public void setText(String text) { assert text != null; this.text = text; setText(); } public void setAuthor(String author) { assert author != null; this.author = author; setText(); } // - -%- - private void setText() { StringBuilder text = new StringBuilder(); text.append(this.author); text.append(" @ "); text.append(this.text); super.setText(text.toString()); } protected void paintComponent(Graphics g) { g.drawString(getText(), 8, 2 * getHeight() / 3); } // ---%-@-%--- ReplyPreviewComponent() { } }